includes example and test; new command echo

This commit is contained in:
Marc Wäckerlin
2015-10-10 14:09:47 +00:00
parent 4f0af7e32a
commit da6971ad0e
8 changed files with 202 additions and 15 deletions

View File

@@ -455,8 +455,25 @@ class Script: public QObject {
"command starts at the begin of a new line. Empty lines are allowed. "
"Lines that start with \"#\" are treated as comments."
"\n\n"
"Subcommands are indented. The first indented line defines the level of "
"indentation. All following lines must be indented by the same level."
"\n\n"
"Note: When a selector is required as parameter, then the selector "
"is a CSS selector that must not contain spaces.";
"is a CSS selector."
"\n\n"
"Thanks to the filter script doxygen-webtester.sed, you cab use the "
"comments for producing doxygen documenation. Just start comments with "
"\"##\" to import them to doxygen. This script is automatically configured, "
"when you use the autotools bootstrap from:\n"
"https://dev.marc.waeckerlin.org/redmine/projects/bootstrap-build-environment";
}
/// set workdir
void path(QString path) {
_path = (path.size()?path:".")+QDir::separator();
}
/// get workdir
QString path() {
return _path;
}
QString commands(Formatting f = PLAIN) const {
QString cmds;
@@ -959,6 +976,7 @@ class Script: public QObject {
std::shared_ptr<xml::Node> _testsuites; ///< only valid within run
QString _testclass;
Command* _command;
QString _path;
};
class Do: public Command {
@@ -1289,7 +1307,13 @@ class Upload: public Command {
Logger log(this, script);
TestWebPage* page(dynamic_cast<TestWebPage*>(frame->page()));
assert(page);
QString filename(script->replacevars(_filename));
QString filename(script->path()+script->replacevars(_filename));
if (!QFileInfo(filename).exists()) {
QStringList files(QFileInfo(filename).dir()
.entryList(QStringList(filename)));
if (files.size()==1) filename=files[0];
}
if (!QFileInfo(filename).exists()) filename=script->replacevars(_filename);
if (!QFileInfo(filename).exists()) {
QStringList files(QFileInfo(filename).dir()
.entryList(QStringList(filename)));
@@ -1751,7 +1775,8 @@ class CaCertificate: public Command {
bool execute(Script* script, QWebFrame*) {
Logger log(this, script);
QString filename(script->replacevars(_filename));
QFile cacertfile(filename);
QFile cacertfile(script->path()+filename);
if (!cacertfile.exists()) cacertfile.setFileName(filename); // try without path
if (!cacertfile.exists() || !cacertfile.open(QIODevice::ReadOnly))
throw FileNotFound(filename);
QSslCertificate cacert(&cacertfile);
@@ -1797,7 +1822,8 @@ class ClientCertificate: public Command {
sslConfig.setProtocol(QSsl::AnyProtocol);
sslConfig.setPeerVerifyMode(QSslSocket::AutoVerifyPeer);
QString filename(script->replacevars(_certfile));
QFile certfile(filename);
QFile certfile(script->path()+filename);
if (!certfile.exists()) certfile.setFileName(filename);
if (!certfile.exists() || !certfile.open(QIODevice::ReadOnly))
throw FileNotFound(filename);
QSslCertificate cert(&certfile);
@@ -1951,7 +1977,7 @@ class Function: public Command {
" quotes. If you need a comma within a value, you must quote.";
}
QString command() const {
return tag()+" "+_name+" "+_vars.join(" ");
return tag()+" "+_name+" "+_vars.join(", ");
}
std::shared_ptr<Command> parse(Script* script, QString args,
QStringList& in, QString file, int line,
@@ -2161,7 +2187,7 @@ class Check: public Command {
}
QString description() const {
return
tag()+" <value1> <op> <value2>\n"+
tag()+" <value1> <cmp> <value2>\n"+
tag()+" <value1>\n"
" <command>"
"\n\n"
@@ -2169,7 +2195,12 @@ class Check: public Command {
" result of a command. The command should be a command that produces an"
" output, such as <do>, which returns the result of JavaScript or"
" <execute>, which returns the output of the executed command, or"
" <call>, which returns the result of the last command.";
" <call>, which returns the result of the last command. "
"The comparision <cmp> can be = ^ ~ < >, "
"which means equal, different, match, "
"less (as integer), bigger (as integer). "
"Match allows a regular expression. "
" less than < (integers), larger than > (integers)";
}
QString command() const {
if (_next)
@@ -2270,6 +2301,35 @@ class For: public Command {
std::shared_ptr<Script> _script;
};
class Echo: public Command {
public:
QString tag() const {
return "echo";
}
QString description() const {
return
tag()+" <text>"
"\n\n"
"Echoes a text to the log.";
}
QString command() const {
return tag();
}
std::shared_ptr<Command> parse(Script*, QString args,
QStringList&, QString, int, int) {
std::shared_ptr<Echo> cmd(new (Echo));
cmd->_text = args;
return cmd;
}
bool execute(Script* script, QWebFrame* frame) {
Logger log(this, script);
log(script->replacevars(_text));
return true;
}
public:
QString _text;
};
/* Template:
class : public Command {
public:
@@ -2393,6 +2453,7 @@ inline void Script::initPrototypes() {
add(new TestCase);
add(new Check);
add(new For);
add(new Echo);
}
#endif

View File

@@ -52,14 +52,17 @@ using namespace NAMESPACE;
*/
QString format(QString txt, int indent = 2, int cpl = 60) {
QString format(QString txt, int indent = 2, int cpl = 80) {
QStringList res;
QStringList lines(txt.split('\n'));
QString ind(indent, ' ');
Q_FOREACH(QString line, lines) {
line.insert(0, ind);
for (int pos(0); line.size()-pos>cpl; ++pos) {
pos=line.lastIndexOf(' ', pos+cpl);
for (int pos(indent); line.size()-pos>cpl; ++pos) {
int pos2=line.lastIndexOf(' ', pos+cpl);
if (pos2>pos) pos=pos2;
else pos=line.indexOf(' ', pos+1);
if (pos<0) break;
line.remove(pos, 1);
line.insert(pos, "\n"+ind);
}
@@ -102,6 +105,9 @@ int main(int argc, char *argv[]) try {
Script script;
parser.setApplicationDescription(help(script));
parser.addHelpOption();
parser.addOption(QCommandLineOption
(QStringList()<<"p"<<"path",
"search <path> within the test scripts", "path"));
parser.addOption(QCommandLineOption
(QStringList()<<"x"<<"xml",
"store XML output in <xmlfile>", "xmlfile"));
@@ -133,6 +139,7 @@ int main(int argc, char *argv[]) try {
<<" built on "<<build_date()<<std::endl;
return 0;
}
if (parser.isSet("path")) script.path(parser.value("path"));
int retries(parser.value("retries").toInt());
int width(parser.value("width").toInt());
int height(parser.value("height").toInt());
@@ -186,6 +193,7 @@ int main(int argc, char *argv[]) try {
script.log("SUCCESS: "+file);
}
} catch (std::exception& e) {
failed = true;
script.log("FAILED: "+file+" with "+e.what());
xml::Node failure("failure");
failure.attr("message") = Script::xmlattr(e.what()).toStdString();
@@ -201,7 +209,6 @@ int main(int argc, char *argv[]) try {
testcase<<failure;
for (int i(testsuites->last().children()); i<expectedtestcases; ++i)
testsuites->last()<<testcase;
failed = true;
}
}
if (expectedtestcases==-1) {