Skip to content

Commit 70eba09

Browse files
committed
Adding common conditions for explicit waits in WebDriverJS
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
1 parent ee18b34 commit 70eba09

17 files changed

+903
-125
lines changed

Diff for: javascript/node/selenium-webdriver/CHANGES.md

+10
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
1+
## v2.44.0-dev
2+
3+
* FIXED: 8000: `Builder.forBrowser()` now accepts an empty string since some
4+
WebDriver implementations ignore the value. A value must still be specified,
5+
however, since it is a required field in WebDriver's wire protocol.
6+
* FIXED: 7994: The `stacktrace` module will not modify stack traces if the
7+
initial parse fails (e.g. the user defined `Error.prepareStackTrace`)
8+
* FIXED: 5855: Added a module (`until`) that defines several common conditions
9+
for use with explicit waits. See updated examples for usage.
10+
111
## v2.43.5
212

313
* FIXED: 7905: `Builder.usingServer(url)` once again returns `this` for

Diff for: javascript/node/selenium-webdriver/README.md

+8-13
Original file line numberDiff line numberDiff line change
@@ -33,21 +33,16 @@ comma-separated list of browsers you wish to test against. For example:
3333
## Usage
3434

3535

36-
var webdriver = require('selenium-webdriver');
36+
var By = require('selenium-webdriver').By,
37+
until = require('selenium-webdriver').until,
38+
firefox = require('selenium-webdriver/firefox');
3739

38-
var driver = new webdriver.Builder().
39-
withCapabilities(webdriver.Capabilities.chrome()).
40-
build();
41-
42-
driver.get('http://www.google.com');
43-
driver.findElement(webdriver.By.name('q')).sendKeys('webdriver');
44-
driver.findElement(webdriver.By.name('btnG')).click();
45-
driver.wait(function() {
46-
return driver.getTitle().then(function(title) {
47-
return title === 'webdriver - Google Search';
48-
});
49-
}, 1000);
40+
var driver = new firefox.Driver();
5041

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

5348
## Documentation

Diff for: javascript/node/selenium-webdriver/example/google_search.js

+9-17
Original file line numberDiff line numberDiff line change
@@ -19,22 +19,14 @@
1919
* Usage: node selenium-webdriver/example/google_search.js
2020
*/
2121

22-
var fs = require('fs');
22+
var By = require('..').By,
23+
until = require('..').until,
24+
firefox = require('../firefox');
2325

24-
var webdriver = require('..'),
25-
remote = require('../remote');
26+
var driver = new firefox.Driver();
2627

27-
var driver = new webdriver.Builder().
28-
withCapabilities(webdriver.Capabilities.chrome()).
29-
build();
30-
31-
driver.get('http://www.google.com');
32-
driver.findElement(webdriver.By.name('q')).sendKeys('webdriver');
33-
driver.findElement(webdriver.By.name('btnG')).click();
34-
driver.wait(function() {
35-
return driver.getTitle().then(function(title) {
36-
return 'webdriver - Google Search' === title;
37-
});
38-
}, 1000);
39-
40-
driver.quit();
28+
driver.get('http://www.google.com/ncr');
29+
driver.findElement(By.name('q')).sendKeys('webdriver');
30+
driver.findElement(By.name('btnG')).click();
31+
driver.wait(until.titleIs('webdriver - Google Search'), 1000);
32+
driver.quit();

Diff for: javascript/node/selenium-webdriver/example/google_search_generator.js

+6-7
Original file line numberDiff line numberDiff line change
@@ -21,18 +21,17 @@
2121
* selenium-webdriver/example/google_search_generator.js
2222
*/
2323

24-
var webdriver = require('..');
24+
var By = require('..').By,
25+
firefox = require('../firefox');
2526

26-
var driver = new webdriver.Builder().
27-
withCapabilities(webdriver.Capabilities.chrome()).
28-
build();
27+
var driver = new firefox.Driver();
2928

30-
driver.get('http://www.google.com');
29+
driver.get('http://www.google.com/ncr');
3130
driver.call(function* () {
32-
var query = yield driver.findElement(webdriver.By.name('q'));
31+
var query = yield driver.findElement(By.name('q'));
3332
query.sendKeys('webdriver');
3433

35-
var submit = yield driver.findElement(webdriver.By.name('btnG'));
34+
var submit = yield driver.findElement(By.name('btnG'));
3635
submit.click();
3736
});
3837

Diff for: javascript/node/selenium-webdriver/example/google_search_test.js

+10-18
Original file line numberDiff line numberDiff line change
@@ -14,36 +14,28 @@
1414
// limitations under the License.
1515

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

21-
var assert = require('assert'),
22-
fs = require('fs');
23-
24-
var webdriver = require('..'),
25-
test = require('../testing'),
26-
remote = require('../remote');
21+
var By = require('..').By,
22+
until = require('..').until,
23+
firefox = require('../firefox'),
24+
test = require('../testing');
2725

2826

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

3230
test.before(function() {
33-
driver = new webdriver.Builder().
34-
withCapabilities(webdriver.Capabilities.chrome()).
35-
build();
31+
driver = new firefox.Driver();
3632
});
3733

3834
test.it('should append query to title', function() {
3935
driver.get('http://www.google.com');
40-
driver.findElement(webdriver.By.name('q')).sendKeys('webdriver');
41-
driver.findElement(webdriver.By.name('btnG')).click();
42-
driver.wait(function() {
43-
return driver.getTitle().then(function(title) {
44-
return 'webdriver - Google Search' === title;
45-
});
46-
}, 1000);
36+
driver.findElement(By.name('q')).sendKeys('webdriver');
37+
driver.findElement(By.name('btnG')).click();
38+
driver.wait(until.titleIs('webdriver - Google Search'), 1000);
4739
});
4840

4941
test.after(function() { driver.quit(); });

Diff for: javascript/node/selenium-webdriver/example/parallel_flows.js

+4-7
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@
1818
* in parallel in separate control flows.
1919
*/
2020

21-
var webdriver = require('..');
21+
var webdriver = require('..'),
22+
until = webdriver.until;
2223

2324
for (var i = 0; i < 3; i++) {
2425
(function(n) {
@@ -28,7 +29,7 @@ for (var i = 0; i < 3; i++) {
2829
});
2930

3031
var driver = new webdriver.Builder().
31-
withCapabilities(webdriver.Capabilities.chrome()).
32+
withCapabilities(webdriver.Capabilities.firefox()).
3233
setControlFlow(flow). // Comment out this line to see the difference.
3334
build();
3435

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

4845
driver.quit();
4946
})(i);

Diff for: javascript/node/selenium-webdriver/index.js

+6
Original file line numberDiff line numberDiff line change
@@ -130,3 +130,9 @@ exports.WebElementPromise = base.require('webdriver.WebElementPromise');
130130
(exports.__defineGetter__('stacktrace', function() {
131131
return base.exportPublicApi('webdriver.stacktrace');
132132
}));
133+
134+
135+
/** @type {webdriver.until.} */
136+
(exports.__defineGetter__('until', function() {
137+
return base.exportPublicApi('webdriver.until');
138+
}));

Diff for: javascript/node/selenium-webdriver/lib/test/index.js

-8
Original file line numberDiff line numberDiff line change
@@ -171,14 +171,6 @@ function TestEnvironment(browserName, server) {
171171
return d.quit();
172172
}
173173
};
174-
175-
this.waitForTitleToBe = function(expected) {
176-
driver.wait(function() {
177-
return driver.getTitle().then(function(title) {
178-
return title === expected;
179-
});
180-
}, 5000, 'Waiting for title to be ' + expected);
181-
};
182174
}
183175

184176

Diff for: javascript/node/selenium-webdriver/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "selenium-webdriver",
3-
"version": "2.43.5",
3+
"version": "2.44.0-dev",
44
"description": "The official WebDriver JavaScript bindings from the Selenium project",
55
"keywords": [
66
"automation",

Diff for: javascript/node/selenium-webdriver/test/element_finding_test.js

+6-6
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,15 @@ var fail = require('assert').fail;
1919

2020
var By = require('..').By,
2121
error = require('..').error,
22+
until = require('..').until,
2223
test = require('../lib/test'),
2324
assert = require('../testing/assert'),
2425
Browser = test.Browser,
2526
Pages = test.Pages;
2627

2728

2829
test.suite(function(env) {
29-
var browsers = env.browsers,
30-
waitForTitleToBe = env.waitForTitleToBe;
30+
var browsers = env.browsers;
3131

3232
var driver;
3333
beforeEach(function() { driver = env.driver; });
@@ -40,14 +40,14 @@ test.suite(function(env) {
4040
driver.get(Pages.formPage);
4141
driver.get(Pages.xhtmlTestPage);
4242
driver.findElement(By.linkText('click me')).click();
43-
waitForTitleToBe('We Arrive Here');
43+
driver.wait(until.titleIs('We Arrive Here'), 5000);
4444
});
4545

4646
describe('By.id()', function() {
4747
test.it('should work', function() {
4848
driver.get(Pages.xhtmlTestPage);
4949
driver.findElement(By.id('linkId')).click();
50-
waitForTitleToBe('We Arrive Here');
50+
driver.wait(until.titleIs('We Arrive Here'), 5000);
5151
});
5252

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

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

8686
test.it('should work when link text contains equals sign', function() {

Diff for: javascript/node/selenium-webdriver/test/page_loading_test.js

+7-7
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,15 @@
1717

1818
var By = require('..').By,
1919
ErrorCode = require('..').error.ErrorCode,
20+
until = require('..').until,
2021
assert = require('../testing/assert'),
2122
test = require('../lib/test'),
2223
Browser = test.Browser,
2324
Pages = test.Pages;
2425

2526

2627
test.suite(function(env) {
27-
var browsers = env.browsers,
28-
waitForTitleToBe = env.waitForTitleToBe;
28+
var browsers = env.browsers;
2929

3030
var driver;
3131
beforeEach(function() { driver = env.driver; });
@@ -74,7 +74,7 @@ test.suite(function(env) {
7474
driver.get(Pages.formPage);
7575

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

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

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

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

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

101101
driver.navigate().back();
102-
waitForTitleToBe('We Leave From Here');
102+
driver.wait(until.titleIs('We Leave From Here'), 5000);
103103

104104
driver.navigate().forward();
105-
waitForTitleToBe('We Arrive Here');
105+
driver.wait(until.titleIs('We Arrive Here'), 5000);
106106
});
107107

108108
test.it('should be able to refresh a page', function() {

Diff for: javascript/node/selenium-webdriver/test/stale_element_test.js

+2-10
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ var fail = require('assert').fail;
1919

2020
var By = require('..').By,
2121
error = require('..').error,
22+
until = require('..').until,
2223
assert = require('../testing/assert'),
2324
test = require('../lib/test'),
2425
Browser = test.Browser,
@@ -39,16 +40,7 @@ test.suite(function(env) {
3940
assert(toBeDeleted.isDisplayed()).isTrue();
4041

4142
driver.findElement(By.id('delete')).click();
42-
driver.wait(function() {
43-
return toBeDeleted.isDisplayed().
44-
then(function() { return false; }).
45-
then(null, function(e) {
46-
if (e.code === error.ErrorCode.STALE_ELEMENT_REFERENCE) {
47-
return true;
48-
}
49-
throw e;
50-
});
51-
}, 5000, 'Element should be stale at this point');
43+
driver.wait(until.stalenessOf(toBeDeleted), 5000);
5244
});
5345

5446
test.it('an element found in a different frame is stale', function() {

Diff for: javascript/node/selenium-webdriver/testing/index.js

+9-22
Original file line numberDiff line numberDiff line change
@@ -30,40 +30,27 @@
3030
* <p>The provided wrappers leverage the {@link webdriver.promise.ControlFlow}
3131
* to simplify writing asynchronous tests:
3232
* <pre><code>
33-
* var webdriver = require('selenium-webdriver'),
34-
* portprober = require('selenium-webdriver/net/portprober'),
35-
* remote = require('selenium-webdriver/remote'),
33+
* var By = require('selenium-webdriver').By,
34+
* until = require('selenium-webdriver').until,
35+
* firefox = require('selenium-webdriver/firefox'),
3636
* test = require('selenium-webdriver/testing');
3737
*
3838
* test.describe('Google Search', function() {
39-
* var driver, server;
39+
* var driver;
4040
*
4141
* test.before(function() {
42-
* server = new remote.SeleniumServer(
43-
* 'path/to/selenium-server-standalone.jar',
44-
* {port: portprober.findFreePort()});
45-
* server.start();
46-
*
47-
* driver = new webdriver.Builder().
48-
* withCapabilities({'browserName': 'firefox'}).
49-
* usingServer(server.address()).
50-
* build();
42+
* driver = new firefox.Driver();
5143
* });
5244
*
5345
* test.after(function() {
5446
* driver.quit();
55-
* server.stop();
5647
* });
5748
*
5849
* test.it('should append query to title', function() {
59-
* driver.get('http://www.google.com');
60-
* driver.findElement(webdriver.By.name('q')).sendKeys('webdriver');
61-
* driver.findElement(webdriver.By.name('btnG')).click();
62-
* driver.wait(function() {
63-
* return driver.getTitle().then(function(title) {
64-
* return 'webdriver - Google Search' === title;
65-
* });
66-
* }, 1000, 'Waiting for title to update');
50+
* driver.get('http://www.google.com/ncr');
51+
* driver.findElement(By.name('q')).sendKeys('webdriver');
52+
* driver.findElement(By.name('btnG')).click();
53+
* driver.wait(until.titleIs('webdriver - Google Search'), 1000);
6754
* });
6855
* });
6956
* </code></pre>

0 commit comments

Comments
 (0)