Last active
August 29, 2015 13:55
-
-
Save NickTulett/8751051 to your computer and use it in GitHub Desktop.
Augment webdriver-sync for use with Jenkins
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
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