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

Fix stack of undefined issue #5513

Open
wants to merge 20 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 75 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
version: 2
jobs:
build:
docker:
- image: circleci/node:10.16-browsers
environment:
# Fix issue with selenium-server in containers.
# See http://github.com/SeleniumHQ/docker-selenium/issues/87
DBUS_SESSION_BUS_ADDRESS: /dev/null
CHROME_REVISION: 652421
CHROMEDRIVER_VERSION: 75.0.3770.90
# To find this revision number:
# 1. Find the exact chrome version you want: https://en.wikipedia.org/wiki/Google_Chrome_version_history
# 2. Put that version in this tool: https://omahaproxy.appspot.com/
# 3. Take the bumber from "Branch Base Position"
# 4. Look for the closest number to that revision in the snapshots: https://commondatastorage.googleapis.com/chromium-browser-snapshots/index.html?prefix=Linux_x64/
# CHROME 74 - 638880
# CHROME 75 - 652421
# CHROME 79 - 706915
steps:
- checkout
- run:
name: Install Dependencies
command: |
sudo apt-get update
sudo apt-get install python-pip openjdk-8-jdk tcpdump

# Install a specific version of Chrome (not latest)
sudo rm -rf /opt/google
sudo rm /usr/local/bin/chromedriver
wget -q -O chrome.zip https://commondatastorage.googleapis.com/chromium-browser-snapshots/Linux_x64/${CHROME_REVISION}/chrome-linux.zip
unzip chrome.zip
rm chrome.zip
sudo ln -sf ${PWD}/chrome-linux/chrome /usr/bin/chromium
sudo ln -sf /usr/bin/chromium /usr/bin/chromium-browser
sudo groupadd -r chrome && sudo useradd -r -g chrome -G audio,video chrome
sudo mkdir -p /home/chrome/reports
sudo chown -R chrome:chrome /home/chrome

- restore_cache:
key: node_modules-{{ .Branch }}-{{ checksum "package-lock.json" }}

- run:
name: NPM Install
command: |
npm i
cd testapp && npm i

- save_cache:
key: node_modules-{{ .Branch }}-{{ checksum "package-lock.json" }}
paths:
- "node_modules"
- "testapp/node_modules"

- run:
name: Lint
command: ./node_modules/.bin/gulp lint

- run:
name: Selenium Start
background: true
command: |
./node_modules/.bin/webdriver-manager update --versions.standalone=3.141.59 --versions.chrome=${CHROMEDRIVER_VERSION} --versions.gecko=v0.26.0
sudo cp ./node_modules/webdriver-manager/selenium/chromedriver_${CHROMEDRIVER_VERSION} /usr/local/bin/chromedriver
./node_modules/.bin/webdriver-manager start --versions.standalone=3.141.59 --versions.chrome=${CHROMEDRIVER_VERSION} --versions.gecko=v0.26.0

- run:
name: TestApp Start
background: true
command: |
npm start

- run:
name: Test
command: npm test
11 changes: 6 additions & 5 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
language: node_js
sudo: false
node_js:
- "6"
- "8"
- "10"
- "12"

env:
global:
@@ -24,9 +24,9 @@ matrix:
- env: "JOB=bstack"
exclude:
- env: JOB=smoke
node_js: "7"
node_js: "10"
- env: JOB=bstack
node_js: "7"
node_js: "10"

addons:
apt:
@@ -42,7 +42,8 @@ before_script:
- npm run install_testapp
- npm run pretest
- mkdir -p $LOGS_DIR
- ./scripts/travis_setup.sh
- scripts/travis_setup.sh


script:
- ./scripts/testserver.sh
43 changes: 43 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,46 @@
# 7.0.0

- ([9d2e18e](https://github.com/angular/protractor/commit/9d2e18e10d82a97bee58193968f22be6cd1f04e9))
refactor: use console.log instead of util.puts

utils.puts is no longer available in Node.JS 12

- ([c281157](https://github.com/angular/protractor/commit/c28115755d4de5c2ad4c43fc11feab26a928982f))
refactor: remove debugger and explore methods

BREAKING CHANGE: Debugger and explore methods are not compatable with Node 8+. Use `debugger`
keyword instead. See: https://goo.gl/MvWqFh

- ([7cdb978](https://github.com/angular/protractor/commit/7cdb978fca5ae3f5ed95a535ea39b9ee91fb6d2d))
build: update several dev packages that have security issues

- ([8e82835](https://github.com/angular/protractor/commit/8e82835024463cdb17813d19589be0e66bac7992))
build: update webdriver-manager

- ([a1fe5f2](https://github.com/angular/protractor/commit/a1fe5f2ad05ab55b1dafd429f0c31fea27ec3e5b))
ci: update tests to run on Node 10 and 12

- ([3fc9220](https://github.com/angular/protractor/commit/3fc9220189a59750226328a837b42802d18e503a))
fix: prototype Pollution vulnerability through outdated yargs package

BREAKING CHANGE:

Node.Js version 6 and 8 are no longer supported. Please update to Node.Js 10+

Closes #5431

# 5.4.4

## Fixes

- fix: security prototype pollution

# 5.4.3

## Fixes

fix(index.ts): Fix exports to unbreak TypeScript 3.7 build

# 5.4.2

## Features
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -6,7 +6,11 @@ Protractor [![Build Status](https://travis-ci.org/angular/protractor.svg?branch=
Compatibility
-------------

Protractor 5 is compatible with nodejs v6 and newer.
Protractor 5 is compatible with Nodejs v6 and v8 only.

Protractor 6 has been deprecated.

Protractor 7 is compatible with Nodejs v10, v12, and newer.

Protractor works with AngularJS versions greater than 1.0.6/1.1.4, and is compatible with Angular applications. Note that for Angular apps, the `binding` and `model` locators are not supported. We recommend using `by.css`.

46 changes: 0 additions & 46 deletions bin/elementexplorer.js

This file was deleted.

72 changes: 0 additions & 72 deletions circle.yml

This file was deleted.

45 changes: 0 additions & 45 deletions docs/debugging.md
Original file line number Diff line number Diff line change
@@ -258,51 +258,6 @@ used from the browser's console.
> window.clientSideScripts.findInputs('username', document.getElementById('#myEl'));
```

**Testing Out Protractor Interactively**

When debugging or first writing test suites, you may find it helpful to
try out Protractor commands without starting up the entire test suite. You can
do this with the element explorer.

To run element explorer, simply run protractor as you normally would, but pass in
the flag --elementExplorer:

protractor --elementExplorer

This will load up the URL on WebDriver and put the terminal into a REPL loop.
You will see a > prompt. The `browser`, `element` and `protractor` variables will
be available. Enter a command such as:

> browser.get('http://www.angularjs.org')

or

> element(by.id('foobar')).getText()

Typing tab at a blank prompt will fill in a suggestion for finding
elements. You can also use the `list(locator)` command to list all elements
matching a locator.

Element explorer will start chrome by default. However, you can specify
another browser, change browser settings, or specify any other config that you
normally would with your protractor test. To do this, pass configs to
protractor like you normally would,
but with the `--elementExplorer` flag set:

protractor [configFile] [options] --elementExplorer

For example, to connect to ChromeDriver directly, use

protractor --directConnect --elementExplorer

Element explore will ignore your specs, not set up your framework (e.g. jasmine,
mocha, cucumber), and only allow you to pass in 1 capability, but will honor
every other parameter in your config.

Note `baseUrl` is used here as the initial page, i.e. element explorer will try
to navigate to `baseUrl` automatically on start.


## Taking Screenshots

WebDriver can snap a screenshot with `browser.takeScreenshot()`. This can be a
7 changes: 4 additions & 3 deletions docs/faq.md
Original file line number Diff line number Diff line change
@@ -187,12 +187,13 @@ is complete before continuing.

How do I switch off an option in the CLI?
-----------------------------------------
i.e. `webdriver-manager update --chrome=false` does not work.
This has to do with the way `optimist` parses command line args. In order to pass a false value, do one of the following:
This has to do with the way `yargs` parses command line args. In order to pass a false value, do one of the following:

1) `webdriver-manager update --chrome=0`

2) `webdriver-manager update --no-chrome` (see https://github.com/substack/node-optimist#negate-fields)
2) `webdriver-manager update --chrome=false`

3) `webdriver-manager update --no-chrome` (see https://github.com/yargs/yargs/blob/HEAD/docs/tricks.md#negate)

Why does Protractor fail when I decorate $timeout?
--------------------------------------------------
112 changes: 47 additions & 65 deletions gulpfile.js
Original file line number Diff line number Diff line change
@@ -1,32 +1,29 @@
'use strict';

var gulp = require('gulp');
var clangFormat = require('clang-format');
var gulpFormat = require('gulp-clang-format');
var runSequence = require('run-sequence');
var spawn = require('child_process').spawn;
var spawnSync = require('child_process').spawnSync;
var tslint = require('gulp-tslint');
var fs = require('fs');
var path = require('path');
var glob = require('glob');
var semver = require('semver');

var runSpawn = function(done, task, opt_arg, opt_io) {
const gulp = require('gulp');
const format = require('gulp-clang-format');
const clangFormat = require('clang-format');
const spawn = require('child_process').spawn;
const tslint = require('gulp-tslint');
const fs = require('fs');
const path = require('path');
const semver = require('semver');

const runSpawn = (done, task, opt_arg, opt_io) => {
opt_arg = typeof opt_arg !== 'undefined' ? opt_arg : [];
var stdio = 'inherit';
const stdio = 'inherit';
if (opt_io === 'ignore') {
stdio = 'ignore';
}
var child = spawn(task, opt_arg, {stdio: stdio});
var running = false;
child.on('close', function() {
const child = spawn(task, opt_arg, {stdio: stdio});
let running = false;
child.on('close', () => {
if (!running) {
running = true;
done();
}
});
child.on('error', function() {
child.on('error', () => {
if (!running) {
console.error('gulp encountered a child error');
running = true;
@@ -35,21 +32,26 @@ var runSpawn = function(done, task, opt_arg, opt_io) {
});
};

gulp.task('tslint', function() {
gulp.task('tslint', () => {
return gulp.src(['lib/**/*.ts', 'spec/**/*.ts', '!spec/install/**/*.ts'])
.pipe(tslint()).pipe(tslint.report());
.pipe(tslint())
.pipe(tslint.report());
});

gulp.task('lint', function(done) {
runSequence('tslint', 'jshint', 'format:enforce', done);
gulp.task('format:enforce', () => {
return gulp.src(['lib/**/*.ts'])
.pipe(format.checkFormat('file', clangFormat,
{verbose: true, fail: true}));
});

gulp.task('lint', gulp.series('tslint', 'format:enforce'));

// prevent contributors from using the wrong version of node
gulp.task('checkVersion', function(done) {
gulp.task('checkVersion', (done) => {
// read minimum node on package.json
var packageJson = JSON.parse(fs.readFileSync(path.resolve('package.json')));
var protractorVersion = packageJson.version;
var nodeVersion = packageJson.engines.node;
const packageJson = JSON.parse(fs.readFileSync(path.resolve('package.json')));
const protractorVersion = packageJson.version;
const nodeVersion = packageJson.engines.node;

if (semver.satisfies(process.version, nodeVersion)) {
done();
@@ -59,60 +61,40 @@ gulp.task('checkVersion', function(done) {
}
});

gulp.task('built:copy', function(done) {
gulp.task('built:copy', () => {
return gulp.src(['lib/**/*.js'])
.pipe(gulp.dest('built/'));
done();
});

gulp.task('webdriver:update', function(done) {
runSpawn(done, 'node', ['bin/webdriver-manager', 'update']);
});

gulp.task('jshint', function(done) {
runSpawn(done, 'node', ['node_modules/jshint/bin/jshint', '-c',
'.jshintrc', 'lib', 'spec', 'scripts',
'--exclude=lib/selenium-webdriver/**/*.js,lib/webdriver-js-extender/**/*.js,' +
'spec/dependencyTest/*.js,spec/install/**/*.js']);
gulp.task('built:copy:typings', () => {
return gulp.src(['lib/selenium-webdriver/**/*.d.ts'])
.pipe(gulp.dest('built/selenium-webdriver/'));
});

gulp.task('format:enforce', function() {
var format = require('gulp-clang-format');
var clangFormat = require('clang-format');
return gulp.src(['lib/**/*.ts']).pipe(
format.checkFormat('file', clangFormat, {verbose: true, fail: true}));
gulp.task('webdriver:update', (done) => {
runSpawn(done, 'node', ['bin/webdriver-manager', 'update',
'--versions.chrome=2.44']);
});

gulp.task('format', function() {
var format = require('gulp-clang-format');
var clangFormat = require('clang-format');
return gulp.src(['lib/**/*.ts'], { base: '.' }).pipe(
format.format('file', clangFormat)).pipe(gulp.dest('.'));
gulp.task('format', () => {
return gulp.src(['lib/**/*.ts'], { base: '.' })
.pipe(format.format('file', clangFormat))
.pipe(gulp.dest('.'));
});

gulp.task('tsc', function(done) {
gulp.task('tsc', (done) => {
runSpawn(done, 'node', ['node_modules/typescript/bin/tsc']);
});

gulp.task('tsc:spec', function(done) {
gulp.task('tsc:spec', (done) => {
runSpawn(done, 'node', ['node_modules/typescript/bin/tsc', '-p', 'ts_spec_config.json']);
});

gulp.task('tsc:es5', function(done) {
runSpawn(done, './scripts/compile_to_es5.sh');
});
gulp.task('prepublish', gulp.series('checkVersion', 'tsc', 'built:copy'));

gulp.task('compile_to_es5', function(done) {
runSequence('checkVersion', 'tsc:es5', 'built:copy', done);
});

gulp.task('prepublish', function(done) {
runSequence('checkVersion', 'tsc', 'built:copy', done);
});

gulp.task('pretest', function(done) {
runSequence('checkVersion',
['webdriver:update', 'tslint', 'format'], 'tsc', 'built:copy', 'tsc:spec', done);
});
gulp.task('pretest', gulp.series(
'checkVersion',
gulp.parallel('webdriver:update', 'tslint', 'format'),
'tsc', 'built:copy', 'built:copy:typings', 'tsc:spec'));

gulp.task('default',['prepublish']);
gulp.task('default', gulp.series('prepublish'));
121 changes: 1 addition & 120 deletions lib/browser.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import {BPClient} from 'blocking-proxy';
import {ActionSequence, By, Capabilities, Command as WdCommand, FileDetector, ICommandName, Navigation, Options, promise as wdpromise, Session, TargetLocator, TouchSequence, until, WebDriver, WebElement, WebElementPromise} from 'selenium-webdriver';
import {By, Command as WdCommand, ICommandName, Navigation, promise as wdpromise, Session, WebDriver, WebElement, WebElementPromise} from 'selenium-webdriver';
import * as url from 'url';
import {extend as extendWD, ExtendedWebDriver} from 'webdriver-js-extender';

import {DebugHelper} from './debugger';
import {build$, build$$, ElementArrayFinder, ElementFinder} from './element';
import {IError} from './exitCodes';
import {ProtractorExpectedConditions} from './expectedConditions';
@@ -315,11 +314,6 @@ export class ProtractorBrowser extends AbstractExtendedWebDriver {
*/
ng12Hybrid: boolean;

/**
* A helper that manages debugging tests.
*/
debugHelper: DebugHelper;

// This index type allows looking up methods by name so we can do mixins.
[key: string]: any;

@@ -364,7 +358,6 @@ export class ProtractorBrowser extends AbstractExtendedWebDriver {
this.getPageTimeout = DEFAULT_GET_PAGE_TIMEOUT;
this.params = {};
this.resetUrl = DEFAULT_RESET_URL;
this.debugHelper = new DebugHelper(this);

let ng12Hybrid_ = false;
Object.defineProperty(this, 'ng12Hybrid', {
@@ -1078,118 +1071,6 @@ export class ProtractorBrowser extends AbstractExtendedWebDriver {
clientSideScripts.getLocationAbsUrl, 'Protractor.getLocationAbsUrl()', rootEl));
}

/**
* Adds a task to the control flow to pause the test and inject helper
* functions
* into the browser, so that debugging may be done in the browser console.
*
* This should be used under node in debug mode, i.e. with
* protractor debug <configuration.js>
*
* @example
* While in the debugger, commands can be scheduled through webdriver by
* entering the repl:
* debug> repl
* > element(by.input('user')).sendKeys('Laura');
* > browser.debugger();
* Press Ctrl + c to leave debug repl
* debug> c
*
* This will run the sendKeys command as the next task, then re-enter the
* debugger.
*/
debugger() {
// jshint debug: true
return this.driver.executeScript(clientSideScripts.installInBrowser)
.then(() => wdpromise.controlFlow().execute(() => {
debugger;
}, 'add breakpoint to control flow'));
}

/**
* See browser.explore().
*/
enterRepl(opt_debugPort?: number) {
return this.explore(opt_debugPort);
}

/**
* Beta (unstable) explore function for entering the repl loop from
* any point in the control flow. Use browser.explore() in your test.
* Does not require changes to the command line (no need to add 'debug').
* Note, if you are wrapping your own instance of Protractor, you must
* expose globals 'browser' and 'protractor' for pause to work.
*
* @example
* element(by.id('foo')).click();
* browser.explore();
* // Execution will stop before the next click action.
* element(by.id('bar')).click();
*
* @param {number=} opt_debugPort Optional port to use for the debugging
* process
*/
explore(opt_debugPort?: number) {
let debuggerClientPath = __dirname + '/debugger/clients/explorer.js';
let onStartFn = (firstTime: boolean) => {
logger.info();
if (firstTime) {
logger.info('------- Element Explorer -------');
logger.info(
'Starting WebDriver debugger in a child process. Element ' +
'Explorer is still beta, please report issues at ' +
'github.com/angular/protractor');
logger.info();
logger.info('Type <tab> to see a list of locator strategies.');
logger.info('Use the `list` helper function to find elements by strategy:');
logger.info(' e.g., list(by.binding(\'\')) gets all bindings.');
logger.info();
}
};
this.debugHelper.initBlocking(debuggerClientPath, onStartFn, opt_debugPort);
}

/**
* Beta (unstable) pause function for debugging webdriver tests. Use
* browser.pause() in your test to enter the protractor debugger from that
* point in the control flow.
* Does not require changes to the command line (no need to add 'debug').
* Note, if you are wrapping your own instance of Protractor, you must
* expose globals 'browser' and 'protractor' for pause to work.
*
* @example
* element(by.id('foo')).click();
* browser.pause();
* // Execution will stop before the next click action.
* element(by.id('bar')).click();
*
* @param {number=} opt_debugPort Optional port to use for the debugging
* process
*/
pause(opt_debugPort?: number): wdpromise.Promise<any> {
if (this.debugHelper.isAttached()) {
logger.info('Encountered browser.pause(), but debugger already attached.');
return wdpromise.when(true);
}
let debuggerClientPath = __dirname + '/debugger/clients/wddebugger.js';
let onStartFn = (firstTime: boolean) => {
logger.info();
logger.info('Encountered browser.pause(). Attaching debugger...');
if (firstTime) {
logger.info();
logger.info('------- WebDriver Debugger -------');
logger.info(
'Starting WebDriver debugger in a child process. Pause is ' +
'still beta, please report issues at github.com/angular/protractor');
logger.info();
logger.info('press c to continue to the next webdriver command');
logger.info('press ^D to detach debugger and resume code execution');
logger.info();
}
};
this.debugHelper.init(debuggerClientPath, onStartFn, opt_debugPort);
}

/**
* Determine if the control flow is enabled.
*
34 changes: 17 additions & 17 deletions lib/cli.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as fs from 'fs';
import * as optimist from 'optimist';
import * as path from 'path';
import * as yargs from 'yargs';

/**
* The command line interface for interacting with the Protractor runner.
@@ -99,7 +99,6 @@ let allowedNames = [
'nodeDebug',
'debuggerServerPort',
'frameworkPath',
'elementExplorer',
'debug',
'logLevel',
'disableChecks',
@@ -115,7 +114,7 @@ let allowedNames = [
'stackTrace'
];

let optimistOptions: any = {
let yargsOptions: any = {
describes: {
help: 'Print Protractor help menu',
version: 'Print Protractor version',
@@ -134,7 +133,6 @@ let optimistOptions: any = {
framework: 'Test framework to use: jasmine, mocha, or custom',
resultJsonOutputFile: 'Path to save JSON test result',
troubleshoot: 'Turn on troubleshooting output',
elementExplorer: 'Interactively test Protractor commands',
debuggerServerPort: 'Start a debugger server at specified port instead of repl',
disableChecks: 'Disable cli checks',
logLevel: 'Define Protractor log level [ERROR, WARN, INFO, DEBUG]'
@@ -148,35 +146,37 @@ let optimistOptions: any = {
build: 'capabilities.build',
grep: 'jasmineNodeOpts.grep',
'invert-grep': 'jasmineNodeOpts.invertGrep',
explorer: 'elementExplorer'
},
strings: {'capabilities.tunnel-identifier': ''}
};

optimist.usage(
yargs.usage(
'Usage: protractor [configFile] [options]\n' +
'configFile defaults to protractor.conf.js\n' +
'The [options] object will override values from the config file.\n' +
'See the reference config for a full list of options.');
for (let key of Object.keys(optimistOptions.describes)) {
optimist.describe(key, optimistOptions.describes[key]);
for (let key of Object.keys(yargsOptions.describes)) {
yargs.describe(key, yargsOptions.describes[key]);
}
for (let key of Object.keys(optimistOptions.aliases)) {
optimist.alias(key, optimistOptions.aliases[key]);
for (let key of Object.keys(yargsOptions.aliases)) {
yargs.alias(key, yargsOptions.aliases[key]);
}
for (let key of Object.keys(optimistOptions.strings)) {
optimist.string(key);
for (let key of Object.keys(yargsOptions.strings)) {
yargs.string(key);
}
optimist.check(function(arg: any) {

yargs.check(function(arg: any) {
if (arg._.length > 1) {
throw new Error('Error: more than one config file specified');
}

return true;
});

let argv: any = optimist.parse(args);
let argv: any = yargs.parse(args);

if (argv.help) {
optimist.showHelp();
yargs.showHelp();
process.exit(0);
}

@@ -229,11 +229,11 @@ if (!configFile) {
}
}

if (!configFile && !argv.elementExplorer && args.length < 3) {
if (!configFile && args.length < 3) {
console.log(
'**you must either specify a configuration file ' +
'or at least 3 options. See below for the options:\n');
optimist.showHelp();
yargs.showHelp();
process.exit(1);
}

280 changes: 0 additions & 280 deletions lib/debugger.ts

This file was deleted.

157 changes: 0 additions & 157 deletions lib/debugger/clients/explorer.js

This file was deleted.

83 changes: 0 additions & 83 deletions lib/debugger/clients/wddebugger.js

This file was deleted.

113 changes: 0 additions & 113 deletions lib/debugger/debuggerCommons.js

This file was deleted.

127 changes: 0 additions & 127 deletions lib/debugger/modes/commandRepl.js

This file was deleted.

143 changes: 0 additions & 143 deletions lib/debugger/modes/debuggerRepl.js

This file was deleted.

5 changes: 1 addition & 4 deletions lib/index.ts
Original file line number Diff line number Diff line change
@@ -2,7 +2,6 @@ import {ElementHelper, ProtractorBrowser} from './browser';
import {ElementArrayFinder, ElementFinder} from './element';
import {ProtractorExpectedConditions} from './expectedConditions';
import {Locator, ProtractorBy} from './locators';
import {PluginConfig, ProtractorPlugin} from './plugins';
import {Ptor} from './ptor';

// Re-export selenium-webdriver types.
@@ -13,12 +12,10 @@ export {Config} from './config';
export {ElementArrayFinder, ElementFinder} from './element';
export {ProtractorExpectedConditions} from './expectedConditions';
export {Locator, ProtractorBy} from './locators';
export {PluginConfig, ProtractorPlugin} from './plugins';
export {Ptor} from './ptor';
export {Runner} from './runner';

export type PluginConfig = PluginConfig;
export type ProtractorPlugin = ProtractorPlugin;

export let utils = {
firefox: require('selenium-webdriver/firefox'),
http: require('selenium-webdriver/http'),
3 changes: 1 addition & 2 deletions lib/launcher.ts
Original file line number Diff line number Diff line change
@@ -159,8 +159,7 @@ let initFn = function(configFile: string, additionalConfig: Config) {
});
})
.then(() => {
// 3) If we're in `elementExplorer` mode, run only that.
if (config.elementExplorer || config.framework === 'explorer') {
if (config.framework === 'explorer') {
if (config.multiCapabilities.length != 1) {
throw new Error('Must specify only 1 browser while using elementExplorer');
} else {
18 changes: 10 additions & 8 deletions lib/util.ts
Original file line number Diff line number Diff line change
@@ -46,16 +46,18 @@ export function runFilenameOrFn_(configDir: string, filenameOrFn: any, args?: an
}
if (typeof filenameOrFn === 'function') {
let results = when(filenameOrFn.apply(null, args), null, (err) => {
if (typeof err === 'string') {
err = new Error(err);
} else {
err = err as Error;
if (!err.stack) {
err.stack = new Error().stack;
if(err){
if (typeof err === 'string') {
err = new Error(err);
} else {
err = err as Error;
if (!err.stack) {
err.stack = new Error().stack;
}
}
err.stack = exports.filterStackTrace(err.stack);
throw err;
}
err.stack = exports.filterStackTrace(err.stack);
throw err;
});
resolvePromise(results);
} else {
5,488 changes: 3,792 additions & 1,696 deletions package-lock.json

Large diffs are not rendered by default.

34 changes: 17 additions & 17 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"name": "protractor",
"description": "Webdriver E2E test wrapper for Angular.",
"version": "7.0.0",
"homepage": "https://github.com/angular/protractor",
"keywords": [
"angular",
@@ -20,43 +21,43 @@
"glob": "^7.0.3",
"jasmine": "2.8.0",
"jasminewd2": "^2.1.0",
"optimist": "~0.6.0",
"q": "1.4.1",
"saucelabs": "^1.5.0",
"selenium-webdriver": "3.6.0",
"source-map-support": "~0.4.0",
"webdriver-js-extender": "2.1.0",
"webdriver-manager": "^12.0.6"
"webdriver-manager": "^12.1.7",
"yargs": "^15.3.1"
},
"devDependencies": {
"@types/node": "^6.0.46",
"@types/chalk": "^0.4.28",
"@types/glob": "^5.0.29",
"@types/jasmine": "^2.5.47",
"@types/jasminewd2": "^2.0.0",
"@types/minimatch": "^2.0.28",
"@types/minimist": "^1.1.28",
"@types/optimist": "^0.0.29",
"body-parser": "~1.15.2",
"@types/node": "^6.0.46",
"@types/yargs": "ts2.6",
"body-parser": "^1.19.0",
"chai": "~3.5.0",
"chai-as-promised": "~5.3.0",
"clang-format": "1.0.49",
"expect.js": "~0.3.1",
"express": "~4.14.0",
"gulp": "^3.9.1",
"express": "^4.17.1",
"gulp": "^4.0.2",
"gulp-clang-format": "1.0.23",
"gulp-tslint": "^7.0.1",
"jshint": "^2.9.2",
"lodash": "^4.5.1",
"jshint": "^2.11.0",
"lodash": "^4.17.15",
"marked": "^0.3.3",
"mocha": "2.5.3",
"mocha": "^7.1.2",
"natives": "^1.1.6",
"rimraf": "~2.5.3",
"run-sequence": "^1.1.5",
"semver": "^5.3.0",
"tslint": "^4.1.1",
"tslint": "^5.20.1",
"tslint-eslint-rules": "^3.1.0",
"typescript": "^2.1.5",
"vrsource-tslint-rules": "^4.0.1"
"typescript": "~2.6.2",
"vrsource-tslint-rules": "^6.0.0"
},
"repository": {
"type": "git",
@@ -80,7 +81,6 @@
},
"license": "MIT",
"engines": {
"node": ">=6.9.x"
},
"version": "5.4.2"
"node": ">=10.13.x"
}
}
32 changes: 6 additions & 26 deletions release.md
Original file line number Diff line number Diff line change
@@ -1,38 +1,24 @@
Protractor Release Checklist
----------------------------
Protractor Release Checklist (5.4 edition)
------------------------------------------

Say the previous release was 0.0.J, the current release is 0.0.K, and the next release will be 0.0.L.
This branch is only for releases in the 5.4 series. This is the last version of Protractor that supports the WebDriver control flow, and is only compatible with Selenium version prior to Selenium 4.

- Check that features and bug fixes are in by looking at the milestone tag for 0.0.K. Create a milestone for 0.0.L, and bump anything that doesn't need to be finished from 0.0.K to 0.0.L.

- Check if there are new versions of [selenium and iedriver](http://selenium-release.storage.googleapis.com/index.html), [chromedriver](http://chromedriver.storage.googleapis.com/index.html), or [latest browsers](https://saucelabs.com/platforms) that the configuration needs to be updated against. We test against the latest two versions of Chrome, Firefox, and IE.

- The latest selenium version should be used in spec/ciFullConf.js, spec/ciSmokeConf.js, and spec/ciNg2Conf.js.
- The versions in config.json/webdriverVersions should be up to date, and you should run `webdriver-manager update` locally.
- The latest version of Chrome and Firefox should be used in spec/ciFullConf.js and spec/ciNg2Conf.js. All other browsers we support should be listed in spec/ciSmokeConf.js.

- Make sure [Travis](https://travis-ci.org/angular/protractor/builds) is passing. Note that there is an 'allowed failures' section in Travis - make sure that all failures are known.
If you need to do a release of Protractor 5, follow these steps:

- Make sure [CircleCI](https://circleci.com/gh/angular/protractor) is passing (this runs `npm test`)

- Make sure .gitignore and .npmignore are updated with any new files that need to be ignored.

- Make sure that the website and doc generation still work. Doing so now, before you update the package.json or CHANGELOG.md, will save you a big headache.
- Run `./scripts/generate-docs.sh HEAD` to generate the docs against the current commit.
- We have to compile down to es5 to get dgeni to work. `generate-docs.sh` can handle some of this but you may have to make minor changes to the codebase/build infrastructure.
- Run the unit and e2e tests for the website.

- Update package.json with a version bump. If the changes are only bug fixes, increment the patch (e.g. 0.0.5 -> 0.0.6), otherwise increment the minor version.
- Update package.json with a version bump. The only releases from this branch should be bug fixes, so you should only be incrementing the patch version.

- Update CHANGELOG.md.
- You can get a list of changes in the correct format by running
```
git log 0.0.J..HEAD --format="- ([%h](https://github.com/angular/protractor/commit/%H)) %n%w(100,2,2)%B" > /tmp/changes.txt
```
- Create a new section in CHANGELOG.md and copy in features (`feat`), big dependency version updates (`deps`), bug fixes (`fix`), and breaking changes. No need to note chores or stylistic changes - the changelog should be primarily useful to someone using Protractor, not developing on it.
- Breaking changes should be in their own section and include before/after examples of how to fix code that needs to change.
- You won't be adding any breaking changes to the changelog, since breaking changes aren't allowed for Protractor 5! If there's a breaking change, something has gone wrong.
- Make a commit with the API and package.json changes titled chore(release): version bump and changelog for 0.0.K.
@@ -46,11 +32,5 @@ Say the previous release was 0.0.J, the current release is 0.0.K, and the next r
- NPM publish
- Update the website. Run `./scripts/generate-docs.sh`, then switch to the `gh-pages` branch, edit the commit message with `git commit --amend`, and push the new website.
- Run e2e test against the published website.
- Let people know
- Have @ProtractorTest tweet about it
- Close the 0.0.K milestone
49 changes: 0 additions & 49 deletions scripts/interactive_tests/interactive_test.js

This file was deleted.

150 changes: 0 additions & 150 deletions scripts/interactive_tests/interactive_test_util.js

This file was deleted.

12 changes: 0 additions & 12 deletions scripts/interactive_tests/with_base_url.js

This file was deleted.

28 changes: 13 additions & 15 deletions scripts/sauce_connect_setup.sh
Original file line number Diff line number Diff line change
@@ -12,13 +12,14 @@ set -e
# before_script:
# - curl https://gist.github.com/santiycr/5139565/raw/sauce_connect_setup.sh | bash

CONNECT_URL="https://saucelabs.com/downloads/sc-4.4.1-linux.tar.gz"
CONNECT_DOWNLOAD="sc-4.5.4-linux.tar.gz"
CONNECT_URL="https://saucelabs.com/downloads/${CONNECT_DOWNLOAD}"
CONNECT_DIR="/tmp/sauce-connect-$RANDOM"
CONNECT_DOWNLOAD="sc-4.4.1-linux.tar.gz"

CONNECT_LOG="$LOGS_DIR/sauce-connect"
CONNECT_STDOUT="$LOGS_DIR/sauce-connect.stdout"
CONNECT_STDERR="$LOGS_DIR/sauce-connect.stderr"
# Log files are not used for now
# CONNECT_LOG="$LOGS_DIR/sauce-connect"
# CONNECT_STDOUT="$LOGS_DIR/sauce-connect.stdout"
# CONNECT_STDERR="$LOGS_DIR/sauce-connect.stderr"

# Get Connect and start it
mkdir -p $CONNECT_DIR
@@ -42,14 +43,11 @@ if [ ! -z "$BROWSER_PROVIDER_READY_FILE" ]; then
fi


echo "Starting Sauce Connect in the background, logging into:"
echo " $CONNECT_LOG"
echo " $CONNECT_STDOUT"
echo " $CONNECT_STDERR"
sauce-connect/bin/sc -u $SAUCE_USERNAME -k $SAUCE_ACCESS_KEY $ARGS \
2> $CONNECT_STDERR 1> $CONNECT_STDOUT &
echo "Starting Sauce Connect in the background, args:"
echo " $ARGS"
sauce-connect/bin/sc -u $SAUCE_USERNAME -k $SAUCE_ACCESS_KEY $ARGS &

# If you need to debug sauce connect, use the full output like so:
#
# sauce-connect/bin/sc -u $SAUCE_USERNAME -k $SAUCE_ACCESS_KEY $ARGS \
# --logfile $CONNECT_LOG 2> $CONNECT_STDERR 1> $CONNECT_STDOUT &
# If you need to debug sauce connect, use the --doctor flag.
# It will print diagnostic messages but will not start a tunnel.
# See https://wiki.saucelabs.com/display/DOCS/Sauce+Connect+Proxy+Debugging+and+Diagnostics+with+--doctor+flag
# sauce-connect/bin/sc -u $SAUCE_USERNAME -k $SAUCE_ACCESS_KEY --doctor $ARGS
3 changes: 0 additions & 3 deletions scripts/test.js
Original file line number Diff line number Diff line change
@@ -46,9 +46,6 @@ var passingTests = [
'node built/cli.js spec/driverProviderUseExistingWebDriver.js',
'node built/cli.js spec/driverProviderUseExistingWebDriver.js --useBlockingProxy',
'node scripts/errorTest.js',
// Interactive Element Explorer tasks
'node scripts/interactive_tests/interactive_test.js',
'node scripts/interactive_tests/with_base_url.js',
// Unit tests
'node node_modules/jasmine/bin/jasmine.js JASMINE_CONFIG_PATH=scripts/unit_test.json',
// Dependency tests
2 changes: 2 additions & 0 deletions scripts/travis_setup.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
if [ $JOB == "bstack" ]; then
echo "Setting up Browser Stack"
./scripts/browserstack_local_setup.sh
else
echo "Setting up Sauce Labs"
./scripts/sauce_connect_setup.sh
./scripts/wait_for_browser_provider.sh
fi
4 changes: 3 additions & 1 deletion spec/basic/elements_spec.js
Original file line number Diff line number Diff line change
@@ -190,7 +190,9 @@ describe('ElementFinder', function() {

});

it('should check equality correctly', function() {
// Chrome 75, client requests a W3C-compliant session
// Failed: unknown command: Cannot call non W3C standard command while in W3C mode
xit('should check equality correctly', function() {
browser.get('index.html#/form');

var usernameInput = element(by.model('username'));
9 changes: 7 additions & 2 deletions spec/environment.js
Original file line number Diff line number Diff line change
@@ -11,7 +11,12 @@ module.exports = {
'browserName':
(process.env.TEST_BROWSER_NAME || 'chrome'),
'version':
(process.env.TEST_BROWSER_VERSION || 'ANY')
(process.env.TEST_BROWSER_VERSION || 'ANY'),
'chromeOptions': {
args: [
"--no-sandbox"
]
}
},

// Default http port to host the web server
@@ -25,4 +30,4 @@ module.exports = {
'http://' + (process.env.HTTP_HOST || 'localhost') +
':' + (process.env.HTTP_PORT || webServerDefaultPort)

};
};
4 changes: 3 additions & 1 deletion spec/ts/basic/element_spec.ts
Original file line number Diff line number Diff line change
@@ -174,7 +174,9 @@ describe('ElementFinder', function() {

});

it('should check equality correctly', async function() {
// Chrome 75, client requests a W3C-compliant session
// Failed: unknown command: Cannot call non W3C standard command while in W3C mode
xit('should check equality correctly', async function() {
await browser.get('index.html#/form');

const usernameInput = element(by.model('username'));
41 changes: 30 additions & 11 deletions testapp/package-lock.json
7 changes: 3 additions & 4 deletions testapp/scripts/web-server.js
Original file line number Diff line number Diff line change
@@ -2,8 +2,7 @@

var express = require('express');
var bodyParser = require('body-parser')
var optimist = require('optimist');
var util = require('util');
var yargs = require('yargs');
var path = require('path');
var env = require('../../spec/environment.js');

@@ -12,7 +11,7 @@ var DEFAULT_PORT = process.env.HTTP_PORT || env.webServerDefaultPort;
var testAppDir = path.resolve(__dirname, '..');
var defaultAngular = require(path.resolve(testAppDir, 'ng1/lib/angular_version.js'));

var argv = optimist.describe('port', 'port').
var argv = yargs.describe('port', 'port').
default('port', DEFAULT_PORT).
describe('ngversion', 'version of AngularJS to use').
default('ngversion', defaultAngular).
@@ -27,7 +26,7 @@ var main = function() {
testApp.use(bodyParser.json());
testApp.use(testMiddleware);
testApp.listen(port);
util.puts(["Starting express web server in", testAppDir ,"on port", port].
console.log(["Starting express web server in", testAppDir ,"on port", port].
join(" "));
};

1 change: 0 additions & 1 deletion tslint.json
Original file line number Diff line number Diff line change
@@ -6,7 +6,6 @@
"rules": {
"no-duplicate-imports": true,
"no-duplicate-variable": true,
"no-jasmine-focus": true,
"no-var-keyword": true,
"semicolon": [true],
"variable-name": [true, "ban-keywords"],