- auto inject the code to web page and run it code on browser(not nodejs).
- transfter running context between two page.
- load browser by configure.
- multi spec supported
- custom nodejs command supported(having some inner command, see reference)
npm install -g webdriver-manager
webdriver-manager update
more is on https://github.com/angular/webdriver-manager
npm install -g wtester
wtester("bing", "http://www.bing.com", null, function (flow, command) {
flow("^.*\\.bing\\.com/(\\?.*)?$", true, function (env, done) {
document.getElementById("sb_form_q").value = "github centny";
document.getElementById("sb_form_go").click();
done();
});
flow("^.*\\.bing\\.com/search.*$", false, function (env, done) {
var as = document.getElementsByTagName("a");
for (var i = 0; i < as.length; i++) {
if (as[i].href == 'https://github.com/Centny') {
done();
return;
}
}
throw "fail";
});
});
exports.config = {
port: 8880,//proxy port
selenium: 'http://127.0.0.1:4444/wd/hub',
specs: [
'testBing.js',
],
capabilities: {
'browserName': 'chrome',
"loggingPrefs": {
"driver": "INFO",
"browser": "ALL"
},
},
};
wtester wtester-conf.js
- download code
git clone https://github.com/Centny/WebTester.git
- start static server
cd WebTester/test
npm install connect serve-static
./run.js
- start webdriver
webdriver-manager start
- run test
cd WebTester/test
wtester wtester-conf.js
name
required,string the case namestart
required,string the start urlopts
optional,object the options for tester, deafult nullctx
object, the initial context to run test.
exec
required,function the flow executor, the argument isflow,command
flow
fuction, adding test case stepcommand
function, adding custom command
murl
required,string the url regex pattern to match page for run the workeropen
required,bool not used nowworkder
required,function the test code which running on browser, the argument isenv,done
env
object, the current env transfter from prefix workderenv.exec
call the remote command byname,args,callback
env.on
monitor the event byname,opts,handler
env.trigger
trigger manual event.done
function, completed current worker, not arguments.
pre
optional,function the workder to initial something for the test workder
name
required,string the command name.workder
required,function the command executor, the argument isenv,args,done
env
object, the enviroment for running workderenv.browser
object, the webdriver object from selenium-webdriverenv.By
object, the By tools from selenium-webdriverenv.until
object, the until tool from selenium-webdriverargs
object, the command arguments from callerdone
function, completed the current worker and return the data or error, the argument isdata,err
tester object contain some event handler and util function.
tester.init
the initial function before call flowtester.readfile
the util to read file sync.
wtester("case1", "http://localhost:8080/web/page1.html", {
//the intitial test case env.
ctx: {
ws: __dirname,
},
}, function(flow, command) {
command("title", function(env, args, done) {
//the custom command on nodejs
env.browser.getTitle().then(function(title) {
done(title, null);
});
});
flow("^http://localhost:8080/web/page1\\.html(\\?.*)?$", true, function(env, done) {
//the test code on page1.html
env.ctx.testing = "login";
env.exec("title", {}, function(data, err) {//exec custom command
if (err) {
throw err;
}
document.getElementById("login").click();
console.log("testing click login done...");
done();
});
}, function(env, done) {
done();
}).debug({});
});
calling webdriver sendkey
by
required, the selector type in id/xpath/css, see more for webdriver document.selector
required, the selector value, like element idfile
optional, the file pathvalue
optional, the value.
wtester("case1", "http://localhost:8080/web/page1.html", {
//the intitial test case env.
ctx: {
ws: __dirname,
},
}, function(flow, command) {
flow("http://localhost:8080/web/page2\\.html(\\?.*)?", false, function(env, done) {
//the test code on page2.html
if (env.ctx.testing != "login") {
throw "fail";
}
document.getElementById("account").value = "abc";
env.exec("sendkeys", {//exec inner command, eg: set file path for input
by: "id",
selector: "file",
file: env.ctx.ws + "/../data/test.txt",
}, function(data, err) {
if (err) {
throw err;
}
var file = document.getElementById("file");
if (!file.value) {
throw "not fild";
}
console.log(file.value);
console.log("testing login done...");
done();
});
}).debug({//debug the test code on page2.
ctx: {
testing: "login",
},
});
});
read file
name
required, the file name
wtester("cmd", "http://localhost:8080/web/page1.html", {
//the intitial test case env.
ctx: {
ws: __dirname,
},
}, function (flow, command, tester) {
flow("^http://localhost:8080/web/page1\\.html(\\?.*)?$", true, function (env, done) {
//the test code on page1.html
env.exec("readfile", {
name: env.ctx.ws + "/../data/test.txt",
}, function (data, err) {
if (data !== "abc") {
throw "error";
}
done();
});
});
});
fullscreen
if do fullscreen when spec start or not
the example config.js
exports.config = {
port: 8880,//proxy port
selenium: 'http://127.0.0.1:4444/wd/hub',
specs: [
'e2e/testSpec.js',
'e2e/testSpec2.js',
{
specs: [
'e2e/testCtx01.js',
'e2e/testCtx02.js'
],
settings: {
"context": 1,
},
},
{
specs: [
'e2e/testSpec.js',
'e2e/testSpec2.js',
],
},
"e2e/testCmd.js",
"e2e/testMulti.js",
"e2e/testTester.js",
],
capabilities: {
'browserName': 'chrome',
"loggingPrefs": {
"driver": "INFO",
"browser": "ALL"
},
"chromeOptions": {
"args": ['--start-maximized']
}
},
settings: {
"fullscreen": 1,
},
};
conf.specs
is not in the same context.e2e/testCtx01.js,e2e/testCtx02.js
is the same context control bycontext:1
wtester("evn", "http://localhost:8080/web/page3.html", null, function (flow, command, tester) {
flow("^http://localhost:8080/web/page3\\.html(\\?.*)?$", true, function (env, done) {
env.on("tg1", true, function (args) {
console.log(args.msg);
trigger2();
});
env.on("tg2", false, function (args) {
console.log(args.msg);
env.trigger("tg3", {
msg: "manual trigger",
});
});
env.on("tg3", true, function (args) {
console.log(args.msg);
env.trigger("tg4");
});
env.on("tg4", true, function (args) {
console.log(args);
env.trigger("tg5", { msg: "after 1s run" });
});
env.on("tg5", 1000, function (args) {
console.log(args.msg);
env.trigger("tg6");
});
env.on("tg6", 0, function (args) {
console.log(args);
env.trigger("tg7", { msg: "after 1.5s run" }, 1500);
});
env.on("tg7", true, function (args) {
console.log(args.msg);
done();
});
trigger1();
});
});
For debug test case on browser, you cant adding <script type="text/javascript" src="e2e/testSpec.js" />
on your page and adding blow code to simple start flow by matchi url
if (typeof wtester === 'undefined') {
if (typeof module !== 'undefined' && module.exports) {//on nodejs debug
wt = require("wtester");
wtester = wt.wtester;
} else {//on browser debug
wtester = function(name, starter, opts, exec) {
exec(function(murl, open, worker, pre) {
return {
debug: function(env) {
if (!env.ctx) {
env.ctx = {};
}
if (pre) {
pre(env, function() {
if (window.location.href.match(murl)) {
worker(env, function() { });
}
});
} else {
if (window.location.href.match(murl)) {
worker(env, function() { });
}
}
},
};
}, function(env, args, done) {
});
};
}
}