Skip to content
This repository was archived by the owner on Jul 29, 2024. It is now read-only.

Commit 12195c1

Browse files
committed
chore(driverProviders): clean up driver provider q usage
- Remove driverProviderUseExistingWebDriver since the generation of the selenium server is already accomplished when providing a selenium address in driverProvider.ts. Also clean up docs and tests. - Use native promises over q promises.
1 parent 02b3cb9 commit 12195c1

17 files changed

+99
-291
lines changed

docs/server-setup.md

-34
Original file line numberDiff line numberDiff line change
@@ -108,37 +108,3 @@ Protractor can test directly against Chrome and Firefox without using a Selenium
108108
- `directConnect: true` - Your test script communicates directly Chrome Driver or Firefox Driver, bypassing any Selenium Server. If this is true, settings for `seleniumAddress` and `seleniumServerJar` will be ignored. If you attempt to use a browser other than Chrome or Firefox an error will be thrown.
109109

110110
The advantage of directly connecting to browser drivers is that your test scripts may start up and run faster.
111-
112-
Re-using an Existing WebDriver
113-
------------------------------
114-
115-
The use case for re-using an existing WebDriver is when you have existing
116-
`selenium-webdriver` code and are already in control of how the WebDriver is
117-
created, but would also like Protractor to use the same browser, so you can
118-
use protractor's element locators and the rest of its API. This could be
119-
done with the `attachSession` driver provider, but the `attachSession` API is
120-
being removed in `selenium-webdriver` 4.0.0.
121-
122-
Instead of a protractor config file, you create a config object in your test
123-
setup code, and add your already-created WebDriver object and base URL.
124-
125-
```javascript
126-
const ProtractorConfigParser = require('protractor/built/configParser').ConfigParser;
127-
const ProtractorRunner = require('protractor/built/runner').Runner;
128-
129-
const ptorConfig = new ProtractorConfigParser().config_;
130-
ptorConfig.baseUrl = myExistingBaseUrl;
131-
ptorConfig.seleniumWebDriver = myExistingWebDriver;
132-
ptorConfig.noGlobals = true; // local preference
133-
134-
// looks similar to protractor/built/runner.js run()
135-
const ptorRunner = new ProtractorRunner(ptorConfig);
136-
ptorRunner.driverProvider_.setupEnv();
137-
const browser = ptorRunner.createBrowser();
138-
ptorRunner.setupGlobals_(browser); // now you can access protractor.$, etc.
139-
```
140-
141-
Note that this driver provider leaves you in control of quitting the driver,
142-
but that also means Protractor API calls that expect the driver to properly
143-
quit and/or restart the browser, e.g. `restart`, `restartSync`, and
144-
`forkNewDriverInstance`, will not behave as documented.

lib/config.ts

-8
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
import {WebDriver} from 'selenium-webdriver';
2-
31
import {PluginConfig} from './plugins';
42

53
export interface Config {
@@ -230,12 +228,6 @@ export interface Config {
230228
*/
231229
firefoxPath?: string;
232230

233-
// ---- 8. To re-use an existing WebDriver object ---------------------------
234-
235-
// This would not appear in a configuration file. Instead a configuration
236-
// object would be created that includes an existing webdriver.
237-
seleniumWebDriver?: WebDriver;
238-
239231
// ---------------------------------------------------------------------------
240232
// ----- What tests to run ---------------------------------------------------
241233
// ---------------------------------------------------------------------------

lib/driverProviders/attachSession.ts

+5-6
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@
33
* It is responsible for setting up the account object, tearing
44
* it down, and setting up the driver correctly.
55
*/
6-
import * as q from 'q';
7-
import {promise as wdpromise, WebDriver} from 'selenium-webdriver';
6+
import {WebDriver} from 'selenium-webdriver';
87

98
import {Config} from '../config';
109
import {Logger} from '../logger';
@@ -25,10 +24,10 @@ export class AttachSession extends DriverProvider {
2524
* @return {q.promise} A promise which will resolve when the environment is
2625
* ready to test.
2726
*/
28-
protected setupDriverEnv(): q.Promise<any> {
27+
protected async setupDriverEnv(): Promise<any> {
2928
logger.info('Using the selenium server at ' + this.config_.seleniumAddress);
3029
logger.info('Using session id - ' + this.config_.seleniumSessionId);
31-
return q(undefined);
30+
return Promise.resolve();
3231
}
3332

3433
/**
@@ -50,7 +49,7 @@ export class AttachSession extends DriverProvider {
5049
*
5150
* @public
5251
*/
53-
quitDriver(): wdpromise.Promise<void> {
54-
return wdpromise.when(undefined);
52+
quitDriver(): Promise<void> {
53+
return Promise.resolve();
5554
}
5655
}

lib/driverProviders/browserStack.ts

+41-46
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@
33
* It is responsible for setting up the account object, tearing
44
* it down, and setting up the driver correctly.
55
*/
6-
import * as https from 'https';
7-
import * as q from 'q';
86
import {Session, WebDriver} from 'selenium-webdriver';
97
import * as util from 'util';
108

@@ -29,59 +27,57 @@ export class BrowserStack extends DriverProvider {
2927
* Hook to update the BrowserStack job status.
3028
* @public
3129
* @param {Object} update
32-
* @return {q.promise} A promise that will resolve when the update is complete.
30+
* @return {Promise} A promise that will resolve when the update is complete.
3331
*/
34-
updateJob(update: any): q.Promise<any> {
35-
let deferredArray = this.drivers_.map((driver: WebDriver) => {
36-
let deferred = q.defer();
32+
async updateJob(update: any): Promise<any> {
33+
let mappedDrivers = this.drivers_.map(async(driver: WebDriver) => {
34+
let session = await driver.getSession();
3735

38-
driver.getSession().then((session: Session) => {
39-
40-
// Fetching BrowserStack session details.
41-
this.browserstackClient.getSession(
42-
session.getId(), function(error: Error, automate_session: any) {
43-
if (error) {
44-
logger.info(
45-
'BrowserStack results available at ' +
46-
'https://www.browserstack.com/automate');
47-
} else {
48-
if (automate_session && automate_session.browser_url) {
49-
logger.info('BrowserStack results available at ' + automate_session.browser_url);
50-
} else {
51-
logger.info(
52-
'BrowserStack results available at ' +
53-
'https://www.browserstack.com/automate');
54-
}
55-
}
56-
});
36+
// Fetching BrowserStack session details.
37+
this.browserstackClient.getSession(
38+
session.getId(), function(error: Error, automate_session: any) {
39+
if (error) {
40+
logger.info(
41+
'BrowserStack results available at ' +
42+
'https://www.browserstack.com/automate');
43+
} else {
44+
if (automate_session && automate_session.browser_url) {
45+
logger.info('BrowserStack results available at ' +
46+
automate_session.browser_url);
47+
} else {
48+
logger.info(
49+
'BrowserStack results available at ' +
50+
'https://www.browserstack.com/automate');
51+
}
52+
}
53+
});
5754

58-
let jobStatus = update.passed ? 'completed' : 'error';
59-
let statusObj = {status: jobStatus};
55+
let jobStatus = update.passed ? 'completed' : 'error';
56+
let statusObj = {status: jobStatus};
6057

61-
// Updating status of BrowserStack session.
62-
this.browserstackClient.updateSession(
63-
session.getId(), statusObj, function(error: Error, automate_session: any) {
64-
if (error) {
65-
throw new BrowserError(
66-
logger, 'Error updating BrowserStack pass/fail status: ' + util.inspect(error));
67-
} else {
68-
logger.info(automate_session);
69-
deferred.resolve();
70-
}
71-
});
58+
// Updating status of BrowserStack session.
59+
this.browserstackClient.updateSession(
60+
session.getId(), statusObj, function(error: Error,
61+
automate_session: any) {
62+
if (error) {
63+
throw new BrowserError(
64+
logger, 'Error updating BrowserStack pass/fail status: ' +
65+
util.inspect(error));
66+
} else {
67+
logger.info(automate_session);
68+
}
7269
});
73-
return deferred.promise;
7470
});
75-
return q.all(deferredArray);
71+
72+
return Promise.all(mappedDrivers);
7673
}
7774

7875
/**
7976
* Configure and launch (if applicable) the object's environment.
80-
* @return {q.promise} A promise which will resolve when the environment is
77+
* @return {promise} A promise which will resolve when the environment is
8178
* ready to test.
8279
*/
83-
protected setupDriverEnv(): q.Promise<any> {
84-
let deferred = q.defer();
80+
protected async setupDriverEnv(): Promise<any> {
8581
this.config_.capabilities['browserstack.user'] = this.config_.browserstackUser;
8682
this.config_.capabilities['browserstack.key'] = this.config_.browserstackKey;
8783
this.config_.seleniumAddress = 'http://hub.browserstack.com/wd/hub';
@@ -99,8 +95,7 @@ export class BrowserStack extends DriverProvider {
9995
(':' + this.config_.specs.toString().replace(/^.*[\\\/]/, ''));
10096
}
10197

102-
logger.info('Using BrowserStack selenium server at ' + this.config_.seleniumAddress);
103-
deferred.resolve();
104-
return deferred.promise;
98+
logger.info(`Using BrowserStack selenium server at ${this.config_.seleniumAddress}`);
99+
return Promise.resolve();
105100
}
106101
}

lib/driverProviders/direct.ts

+2-3
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
*/
66
import * as fs from 'fs';
77
import * as path from 'path';
8-
import * as q from 'q';
98
import {Capabilities, WebDriver} from 'selenium-webdriver';
109
import {Driver as ChromeDriver, ServiceBuilder as ChromeServiceBuilder} from 'selenium-webdriver/chrome';
1110
import {Driver as FirefoxDriver} from 'selenium-webdriver/firefox';
@@ -29,7 +28,7 @@ export class Direct extends DriverProvider {
2928
* @return {q.promise} A promise which will resolve when the environment is
3029
* ready to test.
3130
*/
32-
protected setupDriverEnv(): q.Promise<any> {
31+
protected async setupDriverEnv(): Promise<any> {
3332
switch (this.config_.capabilities.browserName) {
3433
case 'chrome':
3534
logger.info('Using ChromeDriver directly...');
@@ -43,7 +42,7 @@ export class Direct extends DriverProvider {
4342
'browserName ' + this.config_.capabilities.browserName +
4443
' is not supported with directConnect.');
4544
}
46-
return q.fcall(function() {});
45+
return Promise.resolve(function() {});
4746
}
4847

4948
/**

lib/driverProviders/driverProvider.ts

+22-34
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@
33
* It is responsible for setting up the account object, tearing
44
* it down, and setting up the driver correctly.
55
*/
6-
import * as q from 'q';
7-
import {Builder, promise as wdpromise, Session, WebDriver} from 'selenium-webdriver';
6+
import {Builder, Session, WebDriver} from 'selenium-webdriver';
87

98
import {BlockingProxyRunner} from '../bpRunner';
109
import {Config} from '../config';
@@ -68,22 +67,20 @@ export abstract class DriverProvider {
6867
* @public
6968
* @param webdriver instance
7069
*/
71-
quitDriver(driver: WebDriver): wdpromise.Promise<void> {
70+
async quitDriver(driver: WebDriver): Promise<void> {
7271
let driverIndex = this.drivers_.indexOf(driver);
7372
if (driverIndex >= 0) {
7473
this.drivers_.splice(driverIndex, 1);
7574
}
7675

7776
if (driver.getSession() === undefined) {
78-
return wdpromise.when(undefined);
77+
return Promise.resolve(undefined);
7978
} else {
80-
return driver.getSession()
81-
.then<void>((session_: Session) => {
82-
if (session_) {
83-
return driver.quit();
84-
}
85-
})
86-
.catch<void>(function(err: Error) {});
79+
return driver.getSession().then<void>((session_: Session) => {
80+
if (session_) {
81+
return driver.quit();
82+
}
83+
}).catch<void>(function(_: Error) {});
8784
}
8885
}
8986

@@ -93,56 +90,47 @@ export abstract class DriverProvider {
9390
*
9491
* @param drivers {webdriver.WebDriver[]} The webdriver instances
9592
*/
96-
static quitDrivers(provider: DriverProvider, drivers: WebDriver[]): q.Promise<void> {
97-
let deferred = q.defer<void>();
98-
wdpromise
99-
.all(drivers.map((driver: WebDriver) => {
100-
return provider.quitDriver(driver);
101-
}))
102-
.then(
103-
() => {
104-
deferred.resolve();
105-
},
106-
() => {
107-
deferred.resolve();
108-
});
109-
return deferred.promise;
93+
static async quitDrivers(provider: DriverProvider, drivers: WebDriver[]): Promise<void> {
94+
return await Promise.all(
95+
drivers.map(async(driver: WebDriver) => {
96+
await provider.quitDriver(driver);
97+
})).then(() => {});
11098
}
11199

112100
/**
113101
* Default update job method.
114102
* @return a promise
115103
*/
116-
updateJob(update: any): q.Promise<any> {
117-
return q.fcall(function() {});
104+
updateJob(update: any): Promise<any> {
105+
return Promise.resolve(() => {});
118106
};
119107

120108
/**
121109
* Default setup environment method, common to all driver providers.
122110
*/
123-
setupEnv(): q.Promise<any> {
111+
async setupEnv(): Promise<any> {
124112
let driverPromise = this.setupDriverEnv();
125113
if (this.config_.useBlockingProxy && !this.config_.blockingProxyUrl) {
126114
// TODO(heathkit): If set, pass the webDriverProxy to BP.
127-
return driverPromise.then(() => this.bpRunner.start());
115+
await driverPromise.then(() => this.bpRunner.start());
128116
}
129-
return driverPromise;
117+
await driverPromise;
130118
};
131119

132120
/**
133121
* Set up environment specific to a particular driver provider. Overridden
134122
* by each driver provider.
135123
*/
136-
protected abstract setupDriverEnv(): q.Promise<any>;
124+
protected async abstract setupDriverEnv(): Promise<any>;
137125

138126
/**
139127
* Teardown and destroy the environment and do any associated cleanup.
140128
* Shuts down the drivers.
141129
*
142130
* @public
143-
* @return {q.Promise<any>} A promise which will resolve when the environment is down.
131+
* @return {Promise<any>} A promise which will resolve when the environment is down.
144132
*/
145-
teardownEnv(): q.Promise<any> {
146-
return DriverProvider.quitDrivers(this, this.drivers_);
133+
async teardownEnv(): Promise<any> {
134+
await DriverProvider.quitDrivers(this, this.drivers_);
147135
}
148136
}

lib/driverProviders/hosted.ts

+3-5
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@
33
* It is responsible for setting up the account object, tearing
44
* it down, and setting up the driver correctly.
55
*/
6-
import * as q from 'q';
7-
86
import {Config} from '../config';
97
import {Logger} from '../logger';
108

@@ -19,11 +17,11 @@ export class Hosted extends DriverProvider {
1917
/**
2018
* Configure and launch (if applicable) the object's environment.
2119
* @public
22-
* @return {q.promise} A promise which will resolve when the environment is
20+
* @return {Promise} A promise which will resolve when the environment is
2321
* ready to test.
2422
*/
25-
protected setupDriverEnv(): q.Promise<any> {
23+
protected setupDriverEnv(): Promise<any> {
2624
logger.info('Using the selenium server at ' + this.config_.seleniumAddress);
27-
return q.fcall(function() {});
25+
return Promise.resolve(function() {});
2826
}
2927
}

0 commit comments

Comments
 (0)