Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@NickTulett
Last active August 29, 2015 13:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save NickTulett/8751051 to your computer and use it in GitHub Desktop.
Save NickTulett/8751051 to your computer and use it in GitHub Desktop.
Augment webdriver-sync for use with Jenkins
/*
to be required by another script containing the actual webdriver scripts, plus:
var exit = require("exit");//to flush stdout for Jenkins before exiting with a zero/non-zero code
var driverType = process.argv[2] || "Firefox";
var WD = require("./webdriver_sync_jenkins.js")(driverType);
var wd = WD.wd;
var driver = WD.driver;
var $ = WD.$;
*/
module.exports = function (driverType) {
var wd = require('webdriver-sync'),
driver = new wd[driverType + "Driver"],
By = wd.By,
fs = require("fs");
var xml = require('xml');//to create Junit-like output for Jenkins test result
var OutputType = require("C:\\Testing\\node_modules\\webdriver-sync\\src\\interfaces\\OutputType.js");//for specifying screenshot type
assert = function assert(cond, errmsg) {
if (!cond) {
log.error(errmsg);
}
return cond;
}
log = {//creates JUnit-like output for Jenkins
testTag: null,
caseTag: null,
caseCount: 0,
testName: "",
startTest: function log_startTest(testName) {
console.log("Starting " + testName);
this.testName = testName;
this.testTag = [{"testsuite": [ { _attr: {"time": 1, "errors": 0, "name": testName}}]}];
this.caseCount = 0;
},
caseOpen: false,
caseErrors: 0,
testErrors: 0,
caseName: "",
startCase: function log_startCase(caseName) {
if (this.caseOpen) {
this.endCase();
}
this.caseErrors = 0;
this.caseCount++;
//numbering test cases will keep Jenkins test result in correct order
this.caseName = (this.caseCount < 10 ? "00" : this.caseCount < 100 ? "0" : "")
+ this.caseCount + " " + caseName;
this.caseTag = {"testcase": [ { _attr: {
"errors": 0,
"name": this.caseName,
"time": 1}} ]};
console.log("");
console.log("TEST: " + caseName);
this.caseOpen = true;
},
error: function log_error(errorText) {
this.caseErrors++;
this.testErrors++;
console.log("[ERROR] " + errorText);
this.caseTag.testcase.push({"failure": [ { _attr: {"type": "Error"}}, errorText]});
fs.writeFileSync("C:\\Testing\\Jenkins\\workspace\\" + this.testName
+ "\\" + this.caseName + " " + errorText + ".png",
driver.getScreenshotAs(OutputType.BASE64), "base64");
},
endCase: function log_EndCase() {
console.log("TEST ENDED");
this.caseTag.testcase[0]["_attr"].errors = this.caseErrors.toString();
if (!this.caseErrors) {
this.caseTag.testcase.push("SUCCESS");
}
this.testTag[0].testsuite.push(this.caseTag);
this.caseOpen = false;
},
endTest: function log_endTest() {
if (this.caseOpen) {
this.endCase();
}
this.testTag[0].testsuite[0]["_attr"].errors = this.testErrors.toString();
console.log("TESTS COMPLETE");
console.log("Tests run: " + this.caseCount + ", Failures: " + this.testErrors);
fs.writeFileSync("C:\\Testing\\Jenkins\\workspace\\" + this.testName + "\\log.xml",
xml(this.testTag, {"declaration": {"encoding": "UTF-8"}}));
}
}
return {//the webdriver-sync object with syntactic sugar
wd: wd,
driver: driver,
log: log,
test: "http://<tested website domain>/",
go: function WD_go(url) {//timestamp every navigation for debugging
console.log(new Date());
console.log("NAVIGATING TO " + url);
return driver.get(url);
},
$: function WD_findElement(selector, index) {//sizzle-like syntax for locating elements
var element;
var by;
root = driver;
var by = selector.slice(0,1);
if (by.match(/(\.|#|\w)/)) {//e.g. $("#signIn").click();
by = "cssSelector";
}
if (by === "^") {//e.g. $("^Home").click();
by = "partialLinkText";
selector = selector.slice(1);
}
if (by === "<") {//e.g. var listText = $("<ul>").getText().split(/\n/);
by = "tagName";
selector = selector.slice(1, -1);
}
if (by === "'") {//e.g. $("'New Site'").click();
by = "xpath";
selector = "//*[text()=" + selector + "]";
}
if (by === "@") {//e.g. $("@ng-model=\"model.newSite.name\"").set(siteParms.Name);
by = "xpath";
selector = "//*[" + selector + "]";
}
if (selector.slice(0,2) === "//") {
by = "xpath";
}
console.log("LOCATING ELEMENT " + selector + " BY " + by);
element = root.findElements(By[by](selector));
var elementIndex = index || 0;
if (element) {
//return first-if-only or indexed object
if ((element.length === 1) || (elementIndex && (elementIndex | element.length))) {
element.selector = selector;
element = element[elementIndex];
element.set = function setValue(newValue) {//ensure all inputs are logged
console.log("SETTING VALUE " + (selector.match(/password/) ? "********" : newValue));
return element.sendKeys(newValue);
}
}
} else {
console.error(selector + " not found");
}
return element;
},
//make direct JSON calls within the context of the browser (must be logged in to the site in the same session)
getJSON: function WD_getJSON(url) {
var xhr = driver.executeScript(
"xhr = new XMLHttpRequest();" +
"xhr.open('GET', '" + url + "', false);" +
"xhr.send();" +
"return (xhr.status + '###' + xhr.responseText);"//has to be returned as a simple string
);
xhr = xhr.split("###")
return {status: xhr[0], responseText: xhr[1]};//could add other properties if needed
},
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment