Skip to content

Commit

Permalink
Adding common conditions for explicit waits in WebDriverJS
Browse files Browse the repository at this point in the history
Similar in concept to ExpectedConditions from Java:

    driver.wait(until.elementLocated(By.id('foo'), 2000)
        .then(function(el) { el.click(); });
    driver.wait(until.titleIs('Hello, world!'), 5000);

Fixes issue 5855
  • Loading branch information
jleyba committed Oct 16, 2014
1 parent ee18b34 commit 70eba09
Show file tree
Hide file tree
Showing 17 changed files with 903 additions and 125 deletions.
10 changes: 10 additions & 0 deletions javascript/node/selenium-webdriver/CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
## v2.44.0-dev

* FIXED: 8000: `Builder.forBrowser()` now accepts an empty string since some
WebDriver implementations ignore the value. A value must still be specified,
however, since it is a required field in WebDriver's wire protocol.
* FIXED: 7994: The `stacktrace` module will not modify stack traces if the
initial parse fails (e.g. the user defined `Error.prepareStackTrace`)
* FIXED: 5855: Added a module (`until`) that defines several common conditions
for use with explicit waits. See updated examples for usage.

## v2.43.5

* FIXED: 7905: `Builder.usingServer(url)` once again returns `this` for
Expand Down
21 changes: 8 additions & 13 deletions javascript/node/selenium-webdriver/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,21 +33,16 @@ comma-separated list of browsers you wish to test against. For example:
## Usage


var webdriver = require('selenium-webdriver');
var By = require('selenium-webdriver').By,
until = require('selenium-webdriver').until,
firefox = require('selenium-webdriver/firefox');

var driver = new webdriver.Builder().
withCapabilities(webdriver.Capabilities.chrome()).
build();

driver.get('http://www.google.com');
driver.findElement(webdriver.By.name('q')).sendKeys('webdriver');
driver.findElement(webdriver.By.name('btnG')).click();
driver.wait(function() {
return driver.getTitle().then(function(title) {
return title === 'webdriver - Google Search';
});
}, 1000);
var driver = new firefox.Driver();

driver.get('http://www.google.com/ncr');
driver.findElement(By.name('q')).sendKeys('webdriver');
driver.findElement(By.name('btnG')).click();
driver.wait(until.titleIs('webdriver - Google Search'), 1000);
driver.quit();

## Documentation
Expand Down
26 changes: 9 additions & 17 deletions javascript/node/selenium-webdriver/example/google_search.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,22 +19,14 @@
* Usage: node selenium-webdriver/example/google_search.js
*/

var fs = require('fs');
var By = require('..').By,
until = require('..').until,
firefox = require('../firefox');

var webdriver = require('..'),
remote = require('../remote');
var driver = new firefox.Driver();

var driver = new webdriver.Builder().
withCapabilities(webdriver.Capabilities.chrome()).
build();

driver.get('http://www.google.com');
driver.findElement(webdriver.By.name('q')).sendKeys('webdriver');
driver.findElement(webdriver.By.name('btnG')).click();
driver.wait(function() {
return driver.getTitle().then(function(title) {
return 'webdriver - Google Search' === title;
});
}, 1000);

driver.quit();
driver.get('http://www.google.com/ncr');
driver.findElement(By.name('q')).sendKeys('webdriver');
driver.findElement(By.name('btnG')).click();
driver.wait(until.titleIs('webdriver - Google Search'), 1000);
driver.quit();
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,17 @@
* selenium-webdriver/example/google_search_generator.js
*/

var webdriver = require('..');
var By = require('..').By,
firefox = require('../firefox');

var driver = new webdriver.Builder().
withCapabilities(webdriver.Capabilities.chrome()).
build();
var driver = new firefox.Driver();

driver.get('http://www.google.com');
driver.get('http://www.google.com/ncr');
driver.call(function* () {
var query = yield driver.findElement(webdriver.By.name('q'));
var query = yield driver.findElement(By.name('q'));
query.sendKeys('webdriver');

var submit = yield driver.findElement(webdriver.By.name('btnG'));
var submit = yield driver.findElement(By.name('btnG'));
submit.click();
});

Expand Down
28 changes: 10 additions & 18 deletions javascript/node/selenium-webdriver/example/google_search_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,36 +14,28 @@
// limitations under the License.

/**
* @fileoverview An example test that may be run using Mocha. To run, you must
* have the chromedriver installed on the system PATH.
* @fileoverview An example test that may be run using Mocha.
* Usage: mocha -t 10000 selenium-webdriver/example/google_search_test.js
*/

var assert = require('assert'),
fs = require('fs');

var webdriver = require('..'),
test = require('../testing'),
remote = require('../remote');
var By = require('..').By,
until = require('..').until,
firefox = require('../firefox'),
test = require('../testing');


test.describe('Google Search', function() {
var driver;

test.before(function() {
driver = new webdriver.Builder().
withCapabilities(webdriver.Capabilities.chrome()).
build();
driver = new firefox.Driver();
});

test.it('should append query to title', function() {
driver.get('http://www.google.com');
driver.findElement(webdriver.By.name('q')).sendKeys('webdriver');
driver.findElement(webdriver.By.name('btnG')).click();
driver.wait(function() {
return driver.getTitle().then(function(title) {
return 'webdriver - Google Search' === title;
});
}, 1000);
driver.findElement(By.name('q')).sendKeys('webdriver');
driver.findElement(By.name('btnG')).click();
driver.wait(until.titleIs('webdriver - Google Search'), 1000);
});

test.after(function() { driver.quit(); });
Expand Down
11 changes: 4 additions & 7 deletions javascript/node/selenium-webdriver/example/parallel_flows.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@
* in parallel in separate control flows.
*/

var webdriver = require('..');
var webdriver = require('..'),
until = webdriver.until;

for (var i = 0; i < 3; i++) {
(function(n) {
Expand All @@ -28,7 +29,7 @@ for (var i = 0; i < 3; i++) {
});

var driver = new webdriver.Builder().
withCapabilities(webdriver.Capabilities.chrome()).
withCapabilities(webdriver.Capabilities.firefox()).
setControlFlow(flow). // Comment out this line to see the difference.
build();

Expand All @@ -39,11 +40,7 @@ for (var i = 0; i < 3; i++) {
driver.get('http://www.google.com');
driver.findElement(webdriver.By.name('q')).sendKeys('webdriver');
driver.findElement(webdriver.By.name('btnG')).click();
driver.wait(function() {
return driver.getTitle().then(function(title) {
return 'webdriver - Google Search' === title;
});
}, 1000);
driver.wait(until.titleIs('webdriver - Google Search'), 1000);

driver.quit();
})(i);
Expand Down
6 changes: 6 additions & 0 deletions javascript/node/selenium-webdriver/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -130,3 +130,9 @@ exports.WebElementPromise = base.require('webdriver.WebElementPromise');
(exports.__defineGetter__('stacktrace', function() {
return base.exportPublicApi('webdriver.stacktrace');
}));


/** @type {webdriver.until.} */
(exports.__defineGetter__('until', function() {
return base.exportPublicApi('webdriver.until');
}));
8 changes: 0 additions & 8 deletions javascript/node/selenium-webdriver/lib/test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -171,14 +171,6 @@ function TestEnvironment(browserName, server) {
return d.quit();
}
};

this.waitForTitleToBe = function(expected) {
driver.wait(function() {
return driver.getTitle().then(function(title) {
return title === expected;
});
}, 5000, 'Waiting for title to be ' + expected);
};
}


Expand Down
2 changes: 1 addition & 1 deletion javascript/node/selenium-webdriver/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "selenium-webdriver",
"version": "2.43.5",
"version": "2.44.0-dev",
"description": "The official WebDriver JavaScript bindings from the Selenium project",
"keywords": [
"automation",
Expand Down
12 changes: 6 additions & 6 deletions javascript/node/selenium-webdriver/test/element_finding_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,15 @@ var fail = require('assert').fail;

var By = require('..').By,
error = require('..').error,
until = require('..').until,
test = require('../lib/test'),
assert = require('../testing/assert'),
Browser = test.Browser,
Pages = test.Pages;


test.suite(function(env) {
var browsers = env.browsers,
waitForTitleToBe = env.waitForTitleToBe;
var browsers = env.browsers;

var driver;
beforeEach(function() { driver = env.driver; });
Expand All @@ -40,14 +40,14 @@ test.suite(function(env) {
driver.get(Pages.formPage);
driver.get(Pages.xhtmlTestPage);
driver.findElement(By.linkText('click me')).click();
waitForTitleToBe('We Arrive Here');
driver.wait(until.titleIs('We Arrive Here'), 5000);
});

describe('By.id()', function() {
test.it('should work', function() {
driver.get(Pages.xhtmlTestPage);
driver.findElement(By.id('linkId')).click();
waitForTitleToBe('We Arrive Here');
driver.wait(until.titleIs('We Arrive Here'), 5000);
});

test.it('should fail if ID not present on page', function() {
Expand All @@ -73,14 +73,14 @@ test.suite(function(env) {
test.it('should be able to click on link identified by text', function() {
driver.get(Pages.xhtmlTestPage);
driver.findElement(By.linkText('click me')).click();
waitForTitleToBe('We Arrive Here');
driver.wait(until.titleIs('We Arrive Here'), 5000);
});

test.it(
'should be able to find elements by partial link text', function() {
driver.get(Pages.xhtmlTestPage);
driver.findElement(By.partialLinkText('ick me')).click();
waitForTitleToBe('We Arrive Here');
driver.wait(until.titleIs('We Arrive Here'), 5000);
});

test.it('should work when link text contains equals sign', function() {
Expand Down
14 changes: 7 additions & 7 deletions javascript/node/selenium-webdriver/test/page_loading_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,15 @@

var By = require('..').By,
ErrorCode = require('..').error.ErrorCode,
until = require('..').until,
assert = require('../testing/assert'),
test = require('../lib/test'),
Browser = test.Browser,
Pages = test.Pages;


test.suite(function(env) {
var browsers = env.browsers,
waitForTitleToBe = env.waitForTitleToBe;
var browsers = env.browsers;

var driver;
beforeEach(function() { driver = env.driver; });
Expand Down Expand Up @@ -74,7 +74,7 @@ test.suite(function(env) {
driver.get(Pages.formPage);

driver.findElement(By.id('imageButton')).click();
waitForTitleToBe('We Arrive Here');
driver.wait(until.titleIs('We Arrive Here'), 5000);

driver.navigate().back();
assert(driver.getTitle()).equalTo('We Leave From Here');
Expand All @@ -85,7 +85,7 @@ test.suite(function(env) {
driver.get(Pages.xhtmlTestPage);

driver.findElement(By.name('sameWindow')).click();
waitForTitleToBe('This page has iframes');
driver.wait(until.titleIs('This page has iframes'), 5000);

driver.navigate().back();
assert(driver.getTitle()).equalTo('XHTML Test Page');
Expand All @@ -96,13 +96,13 @@ test.suite(function(env) {
driver.get(Pages.formPage);

driver.findElement(By.id('imageButton')).click();
waitForTitleToBe('We Arrive Here');
driver.wait(until.titleIs('We Arrive Here'), 5000);

driver.navigate().back();
waitForTitleToBe('We Leave From Here');
driver.wait(until.titleIs('We Leave From Here'), 5000);

driver.navigate().forward();
waitForTitleToBe('We Arrive Here');
driver.wait(until.titleIs('We Arrive Here'), 5000);
});

test.it('should be able to refresh a page', function() {
Expand Down
12 changes: 2 additions & 10 deletions javascript/node/selenium-webdriver/test/stale_element_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ var fail = require('assert').fail;

var By = require('..').By,
error = require('..').error,
until = require('..').until,
assert = require('../testing/assert'),
test = require('../lib/test'),
Browser = test.Browser,
Expand All @@ -39,16 +40,7 @@ test.suite(function(env) {
assert(toBeDeleted.isDisplayed()).isTrue();

driver.findElement(By.id('delete')).click();
driver.wait(function() {
return toBeDeleted.isDisplayed().
then(function() { return false; }).
then(null, function(e) {
if (e.code === error.ErrorCode.STALE_ELEMENT_REFERENCE) {
return true;
}
throw e;
});
}, 5000, 'Element should be stale at this point');
driver.wait(until.stalenessOf(toBeDeleted), 5000);
});

test.it('an element found in a different frame is stale', function() {
Expand Down
31 changes: 9 additions & 22 deletions javascript/node/selenium-webdriver/testing/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,40 +30,27 @@
* <p>The provided wrappers leverage the {@link webdriver.promise.ControlFlow}
* to simplify writing asynchronous tests:
* <pre><code>
* var webdriver = require('selenium-webdriver'),
* portprober = require('selenium-webdriver/net/portprober'),
* remote = require('selenium-webdriver/remote'),
* var By = require('selenium-webdriver').By,
* until = require('selenium-webdriver').until,
* firefox = require('selenium-webdriver/firefox'),
* test = require('selenium-webdriver/testing');
*
* test.describe('Google Search', function() {
* var driver, server;
* var driver;
*
* test.before(function() {
* server = new remote.SeleniumServer(
* 'path/to/selenium-server-standalone.jar',
* {port: portprober.findFreePort()});
* server.start();
*
* driver = new webdriver.Builder().
* withCapabilities({'browserName': 'firefox'}).
* usingServer(server.address()).
* build();
* driver = new firefox.Driver();
* });
*
* test.after(function() {
* driver.quit();
* server.stop();
* });
*
* test.it('should append query to title', function() {
* driver.get('http://www.google.com');
* driver.findElement(webdriver.By.name('q')).sendKeys('webdriver');
* driver.findElement(webdriver.By.name('btnG')).click();
* driver.wait(function() {
* return driver.getTitle().then(function(title) {
* return 'webdriver - Google Search' === title;
* });
* }, 1000, 'Waiting for title to update');
* driver.get('http://www.google.com/ncr');
* driver.findElement(By.name('q')).sendKeys('webdriver');
* driver.findElement(By.name('btnG')).click();
* driver.wait(until.titleIs('webdriver - Google Search'), 1000);
* });
* });
* </code></pre>
Expand Down

0 comments on commit 70eba09

Please sign in to comment.