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

Commit 5266394

Browse files
committed
deps(selenium): upgrade to selenium 4
- Elements workaround for WebElement.equals - Added a better unhandled rejection warning message in the launcher - Remove global function wrappers for mocha (these wrappers went away with control flow) - Fix the attach to session driver provider Typing exported from Protractor: - removed ActionSequence and EventEmitter - removed promise.Promise - removed Promise, defer, delayed, createFlow, controlFlow, all, fulfilled, filter, when Typings exported from WebDriver: - removed attachToSession - removed WebDriver instance methods: touchActions, call - removed WebElement getSize and getLocation for getRect - removed redefined global vars for testing Tests: - Fix element equals - Add missing 'await' in colorList test. This caused unhandled promise rejections. - Remove control flow related tests - Disable the install test. Installing from "file:../../" is not working. - Fix the attach to session driver provider test to exit with a 1 if errors are encountered
1 parent 4b4e9a9 commit 5266394

25 files changed

+143
-217
lines changed

Diff for: lib/browser.ts

+12-11
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ const DEFER_LABEL = 'NG_DEFER_BOOTSTRAP!';
2121
const DEFAULT_RESET_URL = 'data:text/html,<html></html>';
2222
const DEFAULT_GET_PAGE_TIMEOUT = 10000;
2323

24-
let logger = new Logger('protractor');
24+
let logger = new Logger('browser');
2525

2626
// TODO(cnishina): either remove for loop entirely since this does not export anything
2727
// the user might need since everything is composed (with caveat that this could be a
@@ -505,11 +505,11 @@ export class ProtractorBrowser extends AbstractExtendedWebDriver {
505505
}
506506

507507
// TODO(selenium4): fix promise cast.
508-
return this.driver.schedule(
509-
new Command(CommandName.EXECUTE_SCRIPT)
510-
.setParameter('script', script)
511-
.setParameter('args', scriptArgs),
512-
description) as Promise<any>;
508+
// TODO(selenium4): schedule does not exist on driver. Should use execute instead.
509+
return (this.driver as any)
510+
.execute(new Command(CommandName.EXECUTE_SCRIPT)
511+
.setParameter('script', script)
512+
.setParameter('args', scriptArgs));
513513
}
514514

515515
/**
@@ -527,14 +527,15 @@ export class ProtractorBrowser extends AbstractExtendedWebDriver {
527527
*/
528528
private executeAsyncScript_(script: string|Function, description: string, ...scriptArgs: any[]):
529529
Promise<any> {
530+
// TODO(selenium4): decide what to do with description.
530531
if (typeof script === 'function') {
531532
script = 'return (' + script + ').apply(null, arguments);';
532533
}
533-
return this.driver.schedule(
534-
new Command(CommandName.EXECUTE_ASYNC_SCRIPT)
535-
.setParameter('script', script)
536-
.setParameter('args', scriptArgs),
537-
description) as Promise<any>;
534+
// TODO(selenium4): fix typings. driver.execute should exist
535+
return (this.driver as any)
536+
.execute(new Command(CommandName.EXECUTE_ASYNC_SCRIPT)
537+
.setParameter('script', script)
538+
.setParameter('args', scriptArgs));
538539
}
539540

540541
/**

Diff for: lib/driverProviders/attachSession.ts

+5-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +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 {WebDriver} from 'selenium-webdriver';
6+
import {Session, WebDriver} from 'selenium-webdriver';
77

88
import {Config} from '../config';
99
import {Logger} from '../logger';
@@ -38,7 +38,10 @@ export class AttachSession extends DriverProvider {
3838
getNewDriver(): WebDriver {
3939
const httpClient = new http.HttpClient(this.config_.seleniumAddress);
4040
const executor = new http.Executor(httpClient);
41-
const newDriver = WebDriver.attachToSession(executor, this.config_.seleniumSessionId, null);
41+
const session = new Session(this.config_.seleniumSessionId, null);
42+
43+
// const newDriver = WebDriver.attachToSession(executor, this.config_.seleniumSessionId, null);
44+
const newDriver = new WebDriver(session, executor);
4245
this.drivers_.push(newDriver);
4346
return newDriver;
4447
}

Diff for: lib/element.ts

+7-5
Original file line numberDiff line numberDiff line change
@@ -1124,11 +1124,13 @@ export class ElementFinder extends WebdriverWebElement {
11241124
* @returns {!Promise<boolean>} A promise that will be
11251125
* resolved to whether the two WebElements are equal.
11261126
*/
1127-
equals(element: ElementFinder|WebElement): Promise<any> {
1128-
return WebElement.equals(
1129-
this.getWebElement(),
1130-
(element as any).getWebElement ? (element as ElementFinder).getWebElement() :
1131-
element as WebElement) as Promise<any>;
1127+
async equals(element: ElementFinder|WebElement): Promise<boolean> {
1128+
const a = await this.getWebElement();
1129+
const b = (element as any).getWebElement ? await (element as ElementFinder).getWebElement() :
1130+
element as WebElement;
1131+
// TODO(selenium4): Use `return WebElement.equals(a, b);` when
1132+
// https://github.com/SeleniumHQ/selenium/pull/6749 is fixed.
1133+
return a.getDriver().executeScript('return arguments[0] === arguments[1]', a, b);
11321134
}
11331135
}
11341136

Diff for: lib/frameworks/mocha.js

-59
Original file line numberDiff line numberDiff line change
@@ -13,65 +13,6 @@ exports.run = (runner, specs) => {
1313
require('./setupAfterEach').setup(runner, specs);
1414

1515
return new Promise(async (resolve, reject) => {
16-
// Mocha doesn't set up the ui until the pre-require event, so
17-
// wait until then to load mocha-webdriver adapters as well.
18-
mocha.suite.on('pre-require', () => {
19-
try {
20-
// We need to re-wrap all of the global functions, which `selenium-webdriver/testing` only
21-
// does when it is required. So first we must remove it from the cache.
22-
delete require.cache[require.resolve('selenium-webdriver/testing')];
23-
const seleniumAdapter = require('selenium-webdriver/testing');
24-
25-
// Save unwrapped version
26-
let unwrappedFns = {};
27-
['after', 'afterEach', 'before', 'beforeEach', 'it', 'xit', 'iit'].forEach((fnName) => {
28-
unwrappedFns[fnName] = global[fnName] || Mocha[fnName];
29-
});
30-
31-
const wrapFn = (seleniumWrappedFn, opt_fnName) => {
32-
// This does not work on functions that can be nested (e.g. `describe`)
33-
return function() {
34-
// Set globals to unwrapped version to avoid circular reference
35-
let wrappedFns = {};
36-
for (let fnName in unwrappedFns) {
37-
wrappedFns[fnName] = global[fnName];
38-
global[fnName] = unwrappedFns[fnName];
39-
}
40-
41-
let args = arguments;
42-
// Allow before/after hooks to use names
43-
if (opt_fnName && (arguments.length > 1) && (seleniumWrappedFn.length < 2)) {
44-
global[opt_fnName] = global[opt_fnName].bind(this, args[0]);
45-
args = Array.prototype.slice.call(arguments, 1);
46-
}
47-
48-
try {
49-
seleniumWrappedFn.apply(this, args);
50-
} finally {
51-
// Restore wrapped version
52-
for (fnName in wrappedFns) {
53-
global[fnName] = wrappedFns[fnName];
54-
}
55-
}
56-
};
57-
};
58-
59-
// Wrap functions
60-
global.after = wrapFn(seleniumAdapter.after, 'after');
61-
global.afterEach = wrapFn(seleniumAdapter.afterEach, 'afterEach');
62-
global.before = wrapFn(seleniumAdapter.before, 'before');
63-
global.beforeEach = wrapFn(seleniumAdapter.beforeEach, 'beforeEach');
64-
65-
global.it = wrapFn(seleniumAdapter.it);
66-
global.iit = wrapFn(seleniumAdapter.it.only);
67-
global.xit = wrapFn(seleniumAdapter.xit);
68-
global.it.only = wrapFn(seleniumAdapter.it.only);
69-
global.it.skip = wrapFn(seleniumAdapter.it.skip);
70-
} catch (err) {
71-
reject(err);
72-
}
73-
});
74-
7516
mocha.loadFiles();
7617

7718
try {

Diff for: lib/index.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ import {PluginConfig, ProtractorPlugin} from './plugins';
66
import {Ptor} from './ptor';
77

88
// Re-export selenium-webdriver types.
9-
export {ActionSequence, Browser, Builder, Button, Capabilities, Capability, error, EventEmitter, FileDetector, Key, logging, promise, Session, until, WebDriver, WebElement, WebElementPromise} from 'selenium-webdriver';
9+
// TODO(selenium4): Actions class typings missing. ActionSequence is deprecated.
10+
export {/*Actions,*/ Browser, Builder, Button, Capabilities, Capability, error, EventEmitter, FileDetector, Key, logging, promise, Session, until, WebDriver, WebElement, WebElementPromise} from 'selenium-webdriver';
1011
// Re-export public types.
1112
export {ElementHelper, ProtractorBrowser} from './browser';
1213
export {Config} from './config';

Diff for: lib/launcher.ts

+9-1
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,15 @@ let initFn = async function(configFile: string, additionalConfig: Config) {
171171
});
172172

173173
process.on('unhandledRejection', (reason: Error | any, p: Promise<any>) => {
174-
logger.warn('Unhandled rejection at:', p, 'reason:', reason);
174+
// let e = new Error();
175+
if (reason.stack.match('angular testability are undefined') ||
176+
reason.stack.match('angular is not defined')) {
177+
logger.warn(
178+
'Unhandled promise rejection error: This is usually occurs ' +
179+
'when a browser.get call is made and a previous async call was ' +
180+
'not awaited');
181+
}
182+
logger.warn(p);
175183
});
176184

177185
process.on('exit', (code: number) => {

Diff for: lib/runner.ts

+5-2
Original file line numberDiff line numberDiff line change
@@ -264,8 +264,11 @@ export class Runner extends EventEmitter {
264264
return browser_.waitForAngularEnabled(initProperties.waitForAngularEnabled);
265265
})
266266
.then(() => {
267-
return driver.manage().timeouts().setScriptTimeout(
268-
initProperties.allScriptsTimeout || 0);
267+
// TODO(selenium4): missing typings
268+
// driver.manage().timeouts() <-- does not exist on class Options
269+
return (driver.manage() as any).setTimeouts({
270+
script: initProperties.allScriptsTimeout || 0
271+
});
269272
})
270273
.then(() => {
271274
return browser_;

0 commit comments

Comments
 (0)