Stuart Knightley
@stuk
github.com/Stuk
One async thing after another
browser.get("http://admc.io/wd/test-pages/guinea-pig.html",
function() {
browser.title(function(err, title) {
assert.ok(~title.indexOf('I am a page title - Sauce Labs'),
'Wrong title!');
browser.elementById('i am a link', function(err, el) {
browser.clickElement(el, function() {
browser.eval("window.location.href", function(err, href) {
assert.ok(~href.indexOf('guinea-pig2'));
browser.quit();
});
});
});
});
});
Example from wd.js readme
browser.get("http://admc.io/wd/test-pages/guinea-pig.html",
pageLoaded);
function pageLoaded() {
browser.title(checkTitle);
}
function checkTitle(err, title) {
assert.ok(~title.indexOf('I am a page title - Sauce Labs'), 'Wrong title!');
browser.elementById('i am a link'), clickElement);
}
function clickElement(err, el) {
browser.clickElement(el, getHref);
}
function getHref() {
browser.eval("window.location.href", checkHref);
}
function checkHref(err, href) {
assert.ok(~href.indexOf('guinea-pig2'));
browser.quit();
}
Do something when several tasks have completed
function comparePaths(a, b, cb) {
fs.readFile(a, function (err, aData) {
if (err) return cb(err);
fs.readFile(b, function (err, bData) {
if (err) return cb(err);
compareData(aData, bData, cb);
});
});
};
But not parallel!
function comparePaths(a, b, cb) {
var aData, bData, error;
function done() {
if (!error && aData && bData) compareData(aData, bData, cb);
}
fs.readFile(a, function (err, data) {
if (err && !error) return cb(error = err);
aData = data
done();
});
fs.readFile(b, function (err, data) {
if (err && !error) return cb(error = err);
bData = data
done();
});
};
Boring (and tricky) code to write
Quiz time
function readJSON(fileName, callback) {
fs.readFile(fileName, "utf8", function (err, data) {
if (err) {
callback(err);
return;
}
var object = JSON.parse(data);
callback(null, object);
})
}
readJSON("bad.json", function (err, object) {
if (err) return console.log("Oops");
console.log(object);
});
Oops
SyntaxError: Unexpected end of input
at Object.parse (native)
at /Users/stuart/.../read-json.js:9:27
at fs.readFile (fs.js:176:14)
at Object.oncomplete (fs.js:297:15)
function readJSON(fileName, callback) {
fs.readFile(fileName, "utf8", function (err, data) {
if (err) {
callback(err);
return;
}
var object;
try {
object = JSON.parse(data);
} catch (e) {
return callback(e);
}
callback(null, object);
})
}
Yep, it's promises
.then(function (value) {
// success (resolved)
}, function (error) {
// failure (rejected)
});
.then
returns another promisevar nextPromise = .then(function (value) {
return 2;
})
nextPromise.then(function (value) {
assert(value === 2);
});
.then
returns another promise.then(function (value) {
return 2;
}).then(function (value) {
assert(value === 2);
});
.then(function (value) {
return readFile("a.txt");
}).then(function (value) {
assert(value === /* the contents of a.txt */ );
});
browser.get("http://admc.io/wd/test-pages/guinea-pig.html")
.then(function () {
return browser.title();
}).then(function (title) {
assert.ok(~title.indexOf('I am a page title - Sauce Labs'),
'Wrong title!');
return browser.elementById('i am a link');
}).then(function (el) {
return browser.clickElement(el);
}).then(function () {
return browser.eval("window.location.href");
}).then(function (href) {
assert.ok(~href.indexOf('guinea-pig2'));
}).finally(function () {
browser.quit();
});
var readFile = Q.denodeify(fs.readFile);
function comparePaths(a, b) {
return Q.all([readFile(a), readFile(b)])
.then(function (data) {
return compareData(data[0], data[1]);
});
}
var readFile = Q.denodeify(fs.readFile);
function readJSON(fileName) {
return readFile(fileName, "utf8")
.then(function (data) {
var object = JSON.parse(data);
return object;
});
}
readJSON("bad.json")
.then(function (object) {
console.log(object);
}, function (err) {
console.log("Oops");
});
Control a real web browser with Javascript
var wd, browser, promise;
wd = require("wd");
browser = wd.promiseRemote();
promise = browser.init({ browserName: 'firefox' },
function (err, sessionId) {
// callback
console.log(sessionId);
});
promise.then(function (sessionId) {
// promise
console.log(sessionId)
}).done();
"parses your code and then manipulates the AST to transform the callbacks into calls to then()
"
browser.init({ },
function (err, sessionId) {
// callback
console.log(sessionId);
});
browser.init({ }).then(function (sessionId) {
// callback
console.log(sessionId);
});
browser.init({ }, function (err, sessionId) {
if (err) {
console.error(err);
return;
}
console.log(sessionId);
});
browser.init({}).then(function (sessionId) {
console.log(sessionId);
}, function (err) {
console.error(err);
return;
});
browser.init({ }, function (err, sessionId) {
console.log(sessionId);
browser.eval("return document.title", function (err, title) {
console.log(title);
});
});
browser.init({}).then(function (sessionId) {
console.log(sessionId);
return browser.eval("return document.title");
}).then(function (title) {
console.log(title);
});
browser.init({ }, function (err, sessionId) {
console.log(sessionId);
browser.eval("return document.title", function (err, title) {
console.log(sessionId, title);
});
});
browser.init({}).then(function (sessionId) {
console.log(sessionId);
browser.eval("return document.title").then(function (title) {
console.log(sessionId, title);
});
});