Package Exports
- yiewd
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (yiewd) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
Yiewd
Yiewd is a Wd.js wrapper that uses V8's new
generators for cleaner code! It's called yiewd because it uses the new
yield syntax with wd. yield + wd = yiewd. Amazing, right?
The problem
Let's say we want to write a webdriver test:
var wd = require('wd')
, driver = wd.remote();
driver.init(desiredCaps, function(err, sessionId) {
if (err) return postTest(err);
driver.get("http://mysite.com", function(err) {
if (err) return postTest(err);
driver.elementById("someId", function(err, el) {
if (err) return postTest(err);
el.click(function(err) {
if (err) return postTest(err);
setTimeout(function() {
driver.elementById("anotherThing", function(err, el2) {
if (err) return postTest(err);
el2.text(function(err, text) {
if (err) return postTest(err);
text.should.equal("What the text should be");
driver.quit(postTest);
});
});
}, 1500);
});
});
});
});Yeah, that sucks. Look at that callback pyramid! Look at all those error checks!
The solution
Let's all be a little more sane, shall we?
var wd = require('yiewd');
wd.remote(function*(driver) {
var sessionId, el, el2, text;
sessionId = yield driver.init(desiredCaps);
yield driver.get("http://mysite.com");
el = yield driver.elementById("someId");
yield el.click();
yield driver.sleep(1.5);
el2 = yield driver.elementById("anotherThing")
text = yield el2.text();
text.should.equal("What the text should be");
yield driver.quit();
});Isn't that awesome? If you don't like passing driver around, you can also
make use of Javascript's awesome binding situation to be even more concise:
wd.remote(function*() {
var sessionId, el, el2, text;
sessionId = yield this.init(desiredCaps);
yield this.get("http://mysite.com");
el = yield this.elementById("someId");
yield el.click();
yield this.sleep(1.5);
el2 = yield this.elementById("anotherThing")
text = yield el2.text();
text.should.equal("What the text should be");
yield this.quit();
});How it works
Basically, you pass a generator to wd.remote. This generator receives
a driver object. Now, anytime you would have had a callback, just yield the
function. If anything would have been passed as an argument to the callback,
you'll get it as the assignment to yield.
It takes a slight change of thought, but it's so much better than callbacks.
Enjoy!
Integrating with test suites
It's relatively easy to break up bits of sessions between testcases and so on. Here's what a simple mocha test suite could look like:
describe('my cool feature', function() {
var driver = null; // driver object used across testcases
// global setUp, tearDown
before(function(done) {
yiewd.remote(function*(d) {
driver = d;
yield driver.init(desiredCaps);
done();
});
});
after(function(done) {
driver.run(function*() {
yield driver.quit();
done();
});
});
it('should do some thing', function(done) {
driver.run(function*() {
// test logic
done();
});
});
it('should do another thing', function(done) {
driver.run(function*() {
// test logic
done();
});
});
});Essentially, if you have a driver object originally passed into the generator
argument to yiewd.remote(), you can use driver.run() and pass it another
generator which will take over execution for the driver. Easy!
Requirements
- Node >= 0.11.3 (one with generators)
- Make sure you start your test runner with the
--harmonyflag; this might be non-trivial but for mocha, see below. - For running tests:
npm install -g mocha
Run the Tests
Make sure you have your chromedriver-enabled Selenium server running, then:
mocha -R spec -t 60000 --harmony test/Architecture
This is a simple wrapper around Wd.js that is really easy to maintain: (a) new methods from Wd.js can be added with one word in Yiewd, (b) there's nothing really to maintain beyond the generator glue which should stabilize quickly.
Contributing
Give it a whirl and contribute bugfixes! Pull requests welcome. Biggest area of need right now is filling out our testsuite to make sure everything works correctly.
Acknowledgements
These articles / code samples helped me get started with generators (no code was reused, however):