fixed stupid error in Do::execute; nicer logging

master
Marc Wäckerlin 10 years ago
parent c191ab9c7a
commit 24d419d6b2
  1. 179
      src/commands.hxx

@ -81,19 +81,20 @@ class Logger {
~Logger(); ~Logger();
private: private:
Command* _command; Command* _command;
Command* _previous;
Script* _script; Script* _script;
}; };
class Command: public QObject { class Command: public QObject {
Q_OBJECT; Q_OBJECT;
public: public:
Command(): _log(true), _line(-1) {} Command(): _log(true), _line(-1), _indent(0) {}
virtual ~Command() {} virtual ~Command() {}
virtual QString tag() const = 0; virtual QString tag() const = 0;
virtual QString description() const = 0; virtual QString description() const = 0;
virtual QString command() const = 0; virtual QString command() const = 0;
virtual std::shared_ptr<Command> parse(Script*, QString, virtual std::shared_ptr<Command> parse(Script*, QString,
QStringList&, QString, int) = 0; QStringList&, QString, int, int) = 0;
virtual bool execute(Script*, QWebFrame*) = 0; virtual bool execute(Script*, QWebFrame*) = 0;
void line(int linenr) { void line(int linenr) {
_line = linenr; _line = linenr;
@ -107,6 +108,12 @@ class Command: public QObject {
QString file() const { QString file() const {
return _file; return _file;
} }
void indent(int i) {
_indent = i;
}
int indent() const {
return _indent;
}
bool log() { bool log() {
return _log; return _log;
} }
@ -219,6 +226,7 @@ class Command: public QObject {
private: private:
int _line; int _line;
QString _file; QString _file;
int _indent;
}; };
class Empty: public Command { class Empty: public Command {
@ -236,7 +244,7 @@ class Empty: public Command {
return tag(); return tag();
} }
std::shared_ptr<Command> parse(Script*, QString, std::shared_ptr<Command> parse(Script*, QString,
QStringList&, QString, int) { QStringList&, QString, int, int) {
std::shared_ptr<Empty> cmd(new Empty()); std::shared_ptr<Empty> cmd(new Empty());
return cmd; return cmd;
} }
@ -261,7 +269,7 @@ class Comment: public Command {
return _comment; return _comment;
} }
std::shared_ptr<Command> parse(Script*, QString args, std::shared_ptr<Command> parse(Script*, QString args,
QStringList&, QString, int) { QStringList&, QString, int, int) {
std::shared_ptr<Comment> cmd(new Comment(args)); std::shared_ptr<Comment> cmd(new Comment(args));
return cmd; return cmd;
} }
@ -333,7 +341,7 @@ class Screenshot: public Command {
return tag()+" "+_filename; return tag()+" "+_filename;
} }
std::shared_ptr<Command> parse(Script*, QString args, std::shared_ptr<Command> parse(Script*, QString args,
QStringList&, QString, int) { QStringList&, QString, int, int) {
std::shared_ptr<Screenshot> cmd(new Screenshot()); std::shared_ptr<Screenshot> cmd(new Screenshot());
cmd->_filename = args; cmd->_filename = args;
return cmd; return cmd;
@ -411,12 +419,6 @@ class Script: public QObject {
} }
}; };
public: public:
Script(const Script& o):
QObject(),
_prototypes(o._prototypes),
_script(o._script) {
set(o);
}
static QString xmlattr(QString attr, bool br = false) { static QString xmlattr(QString attr, bool br = false) {
attr.replace("&", "&amp;")//.replace(" ", "&nbsp;") attr.replace("&", "&amp;")//.replace(" ", "&nbsp;")
.replace("\"", "&quot;"); .replace("\"", "&quot;");
@ -434,9 +436,16 @@ class Script: public QObject {
.replace("&nbsp;", " ").replace("&amp;", "&"); .replace("&nbsp;", " ").replace("&amp;", "&");
} }
public: public:
Script(): _clicktype(JAVASCRIPT_CLICK) { Script(): _clicktype(JAVASCRIPT_CLICK), _command(0) {
initPrototypes(); initPrototypes();
} }
Script(const Script& o):
QObject(),
_prototypes(o._prototypes),
_script(o._script),
_command(0) {
set(o);
}
QString syntax() const { QString syntax() const {
return return
"Script syntax is a text file that consists of list of commands. Each " "Script syntax is a text file that consists of list of commands. Each "
@ -494,7 +503,8 @@ class Script: public QObject {
_clicktype = JAVASCRIPT_CLICK; _clicktype = JAVASCRIPT_CLICK;
} }
std::shared_ptr<Command> parseLine(QStringList& in, std::shared_ptr<Command> parseLine(QStringList& in,
QString filename, int linenr) try { QString filename, int linenr,
int indent) try {
std::shared_ptr<Command> command; std::shared_ptr<Command> command;
QString line(in.takeFirst().trimmed()); QString line(in.takeFirst().trimmed());
QString cmd(line), args; QString cmd(line), args;
@ -505,23 +515,24 @@ class Script: public QObject {
} }
Prototypes::const_iterator it(_prototypes.find(cmd)); Prototypes::const_iterator it(_prototypes.find(cmd));
if (it!=_prototypes.end()) { if (it!=_prototypes.end()) {
command = it->second->parse(this, args, in, filename, linenr); command = it->second->parse(this, args, in, filename, linenr, indent);
} else { } else {
command = unknown(line); command = unknown(line);
} }
command->file(filename); command->file(filename);
command->line(linenr); command->line(linenr);
command->indent(indent);
return command; return command;
} catch (Exception& e) { } catch (Exception& e) {
e.line(linenr); e.line(linenr);
e.file(filename); e.file(filename);
throw; throw;
} }
void parse(QStringList in, QString filename, int line = 1) { void parse(QStringList in, QString filename, int line = 1, int indent = 0) {
for (int linenr(0), oldsize(0); for (int linenr(0), oldsize(0);
oldsize=in.size(), in.size(); oldsize=in.size(), in.size();
linenr+=oldsize-in.size()) linenr+=oldsize-in.size())
_script.push_back(parseLine(in, filename, line+linenr)); _script.push_back(parseLine(in, filename, line+linenr, indent));
} }
QStringList print() { QStringList print() {
QStringList result; QStringList result;
@ -673,6 +684,12 @@ class Script: public QObject {
if (!_signals.empty()) throw UnhandledSignals(_signals); if (!_signals.empty()) throw UnhandledSignals(_signals);
return res; return res;
} }
Command* command() {
return _command;
}
void command(Command* cmd) {
_command = cmd;
}
QString& cout() { QString& cout() {
return _cout; return _cout;
} }
@ -835,8 +852,16 @@ class Script: public QObject {
disconnect(&_timer, SIGNAL(timeout()), this, SLOT(timeout())); disconnect(&_timer, SIGNAL(timeout()), this, SLOT(timeout()));
} }
public Q_SLOTS: public Q_SLOTS:
void log(QString text) { void log(QString text, Command* command = 0) {
text = QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss ")+text; QString prefix
(QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss "));
Command* cmd(command?command:_command);
if (cmd)
prefix += QString("%2:%3%1 ")
.arg(QString(' ', cmd->indent()))
.arg(cmd->file(), 20)
.arg(cmd->line(), -4, 10);
text = prefix+text.split('\n').join("\n "+prefix);
logging(text); logging(text);
std::cout<<text<<std::endl<<std::flush; std::cout<<text<<std::endl<<std::flush;
_cout += text + "\n"; _cout += text + "\n";
@ -879,7 +904,7 @@ class Script: public QObject {
return; return;
} }
_ignoreSignalsUntil.clear(); _ignoreSignalsUntil.clear();
log("signal received: loadFinished "+QString(ok?"true":"false")); log(" signal received: loadFinished "+QString(ok?"true":"false"));
_signals.push(std::make_pair("loadFinished", QStringList(sig))); _signals.push(std::make_pair("loadFinished", QStringList(sig)));
} }
void loadStarted() { void loadStarted() {
@ -888,7 +913,7 @@ class Script: public QObject {
return; return;
} }
_ignoreSignalsUntil.clear(); _ignoreSignalsUntil.clear();
log("signal received: loadStarted"); log(" signal received: loadStarted");
_signals.push(std::make_pair("loadStarted", QStringList())); _signals.push(std::make_pair("loadStarted", QStringList()));
} }
void frameChanged() { void frameChanged() {
@ -902,7 +927,7 @@ class Script: public QObject {
return; return;
} }
_ignoreSignalsUntil.clear(); _ignoreSignalsUntil.clear();
log("signal received: urlChanged "+url.toString()); log(" signal received: urlChanged "+url.toString());
_signals.push(std::make_pair("urlChanged", _signals.push(std::make_pair("urlChanged",
QStringList(url.toString()))); QStringList(url.toString())));
} }
@ -930,6 +955,7 @@ class Script: public QObject {
QString _targetdir; QString _targetdir;
std::shared_ptr<xml::Node> _testsuites; ///< only valid within run std::shared_ptr<xml::Node> _testsuites; ///< only valid within run
QString _testclass; QString _testclass;
Command* _command;
}; };
class Do: public Command { class Do: public Command {
@ -948,10 +974,10 @@ class Do: public Command {
"one space"; "one space";
} }
QString command() const { QString command() const {
return tag()+" "+_selector+_javascript; return tag()+" "+_selector+(_javascript.size()?"\n"+_javascript:"");
} }
std::shared_ptr<Command> parse(Script*, QString args, std::shared_ptr<Command> parse(Script*, QString args,
QStringList& in, QString, int) { QStringList& in, QString, int, int) {
std::shared_ptr<Do> cmd(new Do()); std::shared_ptr<Do> cmd(new Do());
cmd->_selector = args.trimmed(); cmd->_selector = args.trimmed();
cmd->_javascript = subCommandBlock(in).join("\n"); cmd->_javascript = subCommandBlock(in).join("\n");
@ -961,12 +987,13 @@ class Do: public Command {
Logger log(this, script); Logger log(this, script);
QWebElement element(frame->documentElement()); QWebElement element(frame->documentElement());
if (_selector.size()) { if (_selector.size()) {
QWebElement element(find(frame, script->replacevars(_selector))); element = find(frame, script->replacevars(_selector));
if (element.isNull()) if (element.isNull())
throw ElementNotFound(script->replacevars(_selector)); throw ElementNotFound(script->replacevars(_selector));
} }
_result = _result =
element.evaluateJavaScript(script->replacevars(_javascript)).toString(); element.evaluateJavaScript(script->replacevars(_javascript)).toString();
log("result: "+(_result.size()?_result:"(void)"));
return true; return true;
} }
private: private:
@ -989,7 +1016,7 @@ class Load: public Command {
return tag()+" "+_url; return tag()+" "+_url;
} }
std::shared_ptr<Command> parse(Script*, QString args, std::shared_ptr<Command> parse(Script*, QString args,
QStringList&, QString, int) { QStringList&, QString, int, int) {
std::shared_ptr<Load> cmd(new Load()); std::shared_ptr<Load> cmd(new Load());
cmd->_url = args; cmd->_url = args;
return cmd; return cmd;
@ -1033,7 +1060,7 @@ class Expect: public Command {
+(_signal._args.size()?" "+_signal._args.join(' '):QString()); +(_signal._args.size()?" "+_signal._args.join(' '):QString());
} }
std::shared_ptr<Command> parse(Script*, QString args, std::shared_ptr<Command> parse(Script*, QString args,
QStringList&, QString, int) { QStringList&, QString, int, int) {
std::shared_ptr<Expect> cmd(new Expect()); std::shared_ptr<Expect> cmd(new Expect());
cmd->_signal._args = args.split(" "); cmd->_signal._args = args.split(" ");
cmd->_signal._signal = cmd->_signal._args.takeFirst(); cmd->_signal._signal = cmd->_signal._args.takeFirst();
@ -1089,7 +1116,7 @@ class Open: public Command {
return tag(); return tag();
} }
std::shared_ptr<Command> parse(Script*, QString, std::shared_ptr<Command> parse(Script*, QString,
QStringList&, QString, int) { QStringList&, QString, int, int) {
std::shared_ptr<Open> cmd(new Open()); std::shared_ptr<Open> cmd(new Open());
return cmd; return cmd;
} }
@ -1117,7 +1144,7 @@ class Sleep: public Command {
return tag()+" "+_time; return tag()+" "+_time;
} }
std::shared_ptr<Command> parse(Script*, QString time, std::shared_ptr<Command> parse(Script*, QString time,
QStringList&, QString, int) { QStringList&, QString, int, int) {
std::shared_ptr<Sleep> cmd(new Sleep()); std::shared_ptr<Sleep> cmd(new Sleep());
cmd->_time = "10"; // default: 10s cmd->_time = "10"; // default: 10s
if (time.size()) cmd->_time = time; if (time.size()) cmd->_time = time;
@ -1155,7 +1182,7 @@ class Exit: public Command {
return tag(); return tag();
} }
std::shared_ptr<Command> parse(Script*, QString, std::shared_ptr<Command> parse(Script*, QString,
QStringList&, QString, int) { QStringList&, QString, int, int) {
std::shared_ptr<Exit> cmd(new Exit()); std::shared_ptr<Exit> cmd(new Exit());
return cmd; return cmd;
} }
@ -1183,7 +1210,7 @@ class IgnoreTo: public Command {
return tag()+" "+_label; return tag()+" "+_label;
} }
std::shared_ptr<Command> parse(Script*, QString args, std::shared_ptr<Command> parse(Script*, QString args,
QStringList&, QString, int) { QStringList&, QString, int, int) {
std::shared_ptr<IgnoreTo> cmd(new IgnoreTo()); std::shared_ptr<IgnoreTo> cmd(new IgnoreTo());
if (!args.size()) throw BadArgument("ignoreto needs a label"); if (!args.size()) throw BadArgument("ignoreto needs a label");
cmd->_label=args; cmd->_label=args;
@ -1213,7 +1240,7 @@ class Label: public Command {
return tag()+" "+_label; return tag()+" "+_label;
} }
std::shared_ptr<Command> parse(Script*, QString args, std::shared_ptr<Command> parse(Script*, QString args,
QStringList&, QString, int) { QStringList&, QString, int, int) {
std::shared_ptr<Label> cmd(new Label()); std::shared_ptr<Label> cmd(new Label());
if (!args.size()) throw BadArgument("label needs a label as parameter"); if (!args.size()) throw BadArgument("label needs a label as parameter");
cmd->_label=args; cmd->_label=args;
@ -1245,7 +1272,7 @@ class Upload: public Command {
return tag()+" "+_selector+" -> "+_filename; return tag()+" "+_selector+" -> "+_filename;
} }
std::shared_ptr<Command> parse(Script*, QString args, std::shared_ptr<Command> parse(Script*, QString args,
QStringList&, QString, int) { QStringList&, QString, int, int) {
std::shared_ptr<Upload> cmd(new Upload()); std::shared_ptr<Upload> cmd(new Upload());
QStringList allargs(args.split("->")); QStringList allargs(args.split("->"));
if (allargs.size()<2) if (allargs.size()<2)
@ -1294,7 +1321,7 @@ class Exists: public Command {
return tag()+" "+_selector+(_text.size()?" -> "+_text:QString()); return tag()+" "+_selector+(_text.size()?" -> "+_text:QString());
} }
std::shared_ptr<Command> parse(Script*, QString args, std::shared_ptr<Command> parse(Script*, QString args,
QStringList&, QString, int) { QStringList&, QString, int, int) {
std::shared_ptr<Exists> cmd(new Exists()); std::shared_ptr<Exists> cmd(new Exists());
QStringList allargs(args.split("->")); QStringList allargs(args.split("->"));
if (allargs.size()<2) { if (allargs.size()<2) {
@ -1347,7 +1374,7 @@ class Not: public Command {
return tag()+" "+_selector+(_text.size()?" -> "+_text:QString()); return tag()+" "+_selector+(_text.size()?" -> "+_text:QString());
} }
std::shared_ptr<Command> parse(Script*, QString args, std::shared_ptr<Command> parse(Script*, QString args,
QStringList&, QString, int) { QStringList&, QString, int, int) {
std::shared_ptr<Not> cmd(new Not()); std::shared_ptr<Not> cmd(new Not());
QStringList allargs(args.split("->")); QStringList allargs(args.split("->"));
if (allargs.size()<2) { if (allargs.size()<2) {
@ -1398,7 +1425,7 @@ class Execute: public Command {
+(script.size()?"\n"+script.join("\n"):QString()); +(script.size()?"\n"+script.join("\n"):QString());
} }
std::shared_ptr<Command> parse(Script*, QString args, std::shared_ptr<Command> parse(Script*, QString args,
QStringList& in, QString, int) { QStringList& in, QString, int, int) {
std::shared_ptr<Execute> cmd(new Execute()); std::shared_ptr<Execute> cmd(new Execute());
cmd->_args = args.split(' '); cmd->_args = args.split(' ');
cmd->_command = cmd->_args.takeFirst(); cmd->_command = cmd->_args.takeFirst();
@ -1428,6 +1455,7 @@ class Execute: public Command {
QString stdout(exec.readAllStandardOutput()); QString stdout(exec.readAllStandardOutput());
QString stderr(exec.readAllStandardError()); QString stderr(exec.readAllStandardError());
_result = stdout; _result = stdout;
log("result: "+(_result.size()?_result:"(void)"));
script->log(stdout); script->log(stdout);
if (exec.exitCode()!=0 || exec.exitStatus()!=QProcess::NormalExit) if (exec.exitCode()!=0 || exec.exitStatus()!=QProcess::NormalExit)
throw ScriptExecutionFailed(command, args, scripttxt, throw ScriptExecutionFailed(command, args, scripttxt,
@ -1461,10 +1489,11 @@ class Download: public Command {
+_next->command(); +_next->command();
} }
std::shared_ptr<Command> parse(Script* script, QString args, std::shared_ptr<Command> parse(Script* script, QString args,
QStringList& in, QString file, int line) { QStringList& in, QString file, int line,
int indent) {
std::shared_ptr<Download> cmd(new Download()); std::shared_ptr<Download> cmd(new Download());
cmd->_filename = args.trimmed(); cmd->_filename = args.trimmed();
cmd->_next = script->parseLine(in, file, line+1); cmd->_next = script->parseLine(in, file, line+1, indent+1);
cmd->_next->log(false); // suppress logging of subcommand cmd->_next->log(false); // suppress logging of subcommand
return cmd; return cmd;
} }
@ -1541,7 +1570,7 @@ class Click: public Command {
:"")+" "+_selector; :"")+" "+_selector;
} }
std::shared_ptr<Command> parse(Script*, QString args, std::shared_ptr<Command> parse(Script*, QString args,
QStringList&, QString, int) { QStringList&, QString, int, int) {
std::shared_ptr<Click> cmd(new Click()); std::shared_ptr<Click> cmd(new Click());
if (args.trimmed().contains(QRegularExpression("^realmouse "))) if (args.trimmed().contains(QRegularExpression("^realmouse ")))
cmd->_clicktype = Script::REAL_MOUSE_CLICK; cmd->_clicktype = Script::REAL_MOUSE_CLICK;
@ -1556,17 +1585,16 @@ class Click: public Command {
QString clicktarget(script->replacevars(_selector)); QString clicktarget(script->replacevars(_selector));
switch (_clicktype ? *_clicktype : script->clicktype()) { switch (_clicktype ? *_clicktype : script->clicktype()) {
case Script::REAL_MOUSE_CLICK: { case Script::REAL_MOUSE_CLICK: {
log("Script::REAL_MOUSE_CLICK");
realMouseClick(frame, clicktarget); realMouseClick(frame, clicktarget);
break; break;
} }
case Script::JAVASCRIPT_CLICK: case Script::JAVASCRIPT_CLICK:
default: { default: {
log("Script::JAVASCRIPT_CLICK");
QWebElement element(find(frame, clicktarget)); QWebElement element(find(frame, clicktarget));
if (element.isNull()) if (element.isNull())
throw ElementNotFound(clicktarget); throw ElementNotFound(clicktarget);
_result = element.evaluateJavaScript("this.click();").toString(); _result = element.evaluateJavaScript("this.click();").toString();
if (_result.size()) log("result: "+_result.size());
break; break;
} }
} }
@ -1602,14 +1630,15 @@ class Set: public Command {
return tag()+" "+_name+" = "+_value; return tag()+" "+_name+" = "+_value;
} }
std::shared_ptr<Command> parse(Script* script, QString args, std::shared_ptr<Command> parse(Script* script, QString args,
QStringList& in, QString file, int line) { QStringList& in, QString file, int line,
int indent) {
std::shared_ptr<Set> cmd(new Set()); std::shared_ptr<Set> cmd(new Set());
cmd->_next = 0; cmd->_next = 0;
QStringList allargs(args.split("=")); QStringList allargs(args.split("="));
cmd->_name = allargs.takeFirst().trimmed(); cmd->_name = allargs.takeFirst().trimmed();
cmd->_value = allargs.join("=").trimmed(); cmd->_value = allargs.join("=").trimmed();
if (!args.contains('=')) { if (!args.contains('=')) {
cmd->_next = script->parseLine(in, file, line+1); cmd->_next = script->parseLine(in, file, line+1, indent+1);
cmd->_next->log(false); // suppress logging of subcommand cmd->_next->log(false); // suppress logging of subcommand
} }
return cmd; return cmd;
@ -1647,7 +1676,7 @@ class UnSet: public Command {
return tag()+" "+_name; return tag()+" "+_name;
} }
std::shared_ptr<Command> parse(Script*, QString args, std::shared_ptr<Command> parse(Script*, QString args,
QStringList&, QString, int) { QStringList&, QString, int, int) {
std::shared_ptr<UnSet> cmd(new UnSet()); std::shared_ptr<UnSet> cmd(new UnSet());
cmd->_name = args; cmd->_name = args;
return cmd; return cmd;
@ -1676,7 +1705,7 @@ class Timeout: public Command {
return tag()+" "+_timeout; return tag()+" "+_timeout;
} }
std::shared_ptr<Command> parse(Script*, QString args, std::shared_ptr<Command> parse(Script*, QString args,
QStringList&, QString, int) { QStringList&, QString, int, int) {
std::shared_ptr<Timeout> cmd(new Timeout()); std::shared_ptr<Timeout> cmd(new Timeout());
cmd->_timeout = args; cmd->_timeout = args;
return cmd; return cmd;
@ -1709,7 +1738,7 @@ class CaCertificate: public Command {
return tag()+" "+_filename; return tag()+" "+_filename;
} }
std::shared_ptr<Command> parse(Script*, QString args, std::shared_ptr<Command> parse(Script*, QString args,
QStringList&, QString, int) { QStringList&, QString, int, int) {
std::shared_ptr<CaCertificate> cmd(new (CaCertificate)); std::shared_ptr<CaCertificate> cmd(new (CaCertificate));
cmd->_filename = args.trimmed(); cmd->_filename = args.trimmed();
return cmd; return cmd;
@ -1748,7 +1777,7 @@ class ClientCertificate: public Command {
return tag()+" "+_certfile+" "+_keyfile+" "+_password; return tag()+" "+_certfile+" "+_keyfile+" "+_password;
} }
std::shared_ptr<Command> parse(Script*, QString args, std::shared_ptr<Command> parse(Script*, QString args,
QStringList&, QString, int) { QStringList&, QString, int, int) {
std::shared_ptr<ClientCertificate> cmd(new (ClientCertificate)); std::shared_ptr<ClientCertificate> cmd(new (ClientCertificate));
QStringList s(args.trimmed().split(' ')); QStringList s(args.trimmed().split(' '));
if (s.size()<3) throw MissingArguments(args, "certfile keyfile password"); if (s.size()<3) throw MissingArguments(args, "certfile keyfile password");
@ -1812,7 +1841,7 @@ class ClickType: public Command {
} }
} }
std::shared_ptr<Command> parse(Script* script, QString args, std::shared_ptr<Command> parse(Script* script, QString args,
QStringList&, QString, int) { QStringList&, QString, int, int) {
std::shared_ptr<ClickType> cmd(new ClickType()); std::shared_ptr<ClickType> cmd(new ClickType());
QString choice(script->replacevars(args).trimmed()); QString choice(script->replacevars(args).trimmed());
if (choice=="realmouse") if (choice=="realmouse")
@ -1856,7 +1885,7 @@ class SetValue: public Command {
return tag()+" "+_selector+" -> "+_value; return tag()+" "+_selector+" -> "+_value;
} }
std::shared_ptr<Command> parse(Script*, QString args, std::shared_ptr<Command> parse(Script*, QString args,
QStringList&, QString, int) { QStringList&, QString, int, int) {
std::shared_ptr<SetValue> cmd(new SetValue()); std::shared_ptr<SetValue> cmd(new SetValue());
QStringList allargs(args.split("->")); QStringList allargs(args.split("->"));
if (allargs.size()<2) if (allargs.size()<2)
@ -1920,7 +1949,8 @@ class Function: public Command {
return tag()+" "+_name+" "+_vars.join(" "); return tag()+" "+_name+" "+_vars.join(" ");
} }
std::shared_ptr<Command> parse(Script* script, QString args, std::shared_ptr<Command> parse(Script* script, QString args,
QStringList& in, QString file, int line) { QStringList& in, QString file, int line,
int indent) {
std::shared_ptr<Function> cmd(new Function()); std::shared_ptr<Function> cmd(new Function());
if (!args.size()) throw BadArgument(tag()+" requires a <name>"); if (!args.size()) throw BadArgument(tag()+" requires a <name>");
QStringList allargs(args.split(" ", QString::SkipEmptyParts)); QStringList allargs(args.split(" ", QString::SkipEmptyParts));
@ -1928,7 +1958,7 @@ class Function: public Command {
cmd->_vars = commaSeparatedList(allargs.join(' ')); cmd->_vars = commaSeparatedList(allargs.join(' '));
script->function(cmd->_name, cmd); script->function(cmd->_name, cmd);
cmd->_script = std::shared_ptr<Script>(new Script); cmd->_script = std::shared_ptr<Script>(new Script);
cmd->_script->parse(subCommandBlock(in), file, line+1); cmd->_script->parse(subCommandBlock(in), file, line+1, indent+1);
return cmd; return cmd;
} }
bool execute(Script* script, QWebFrame*) { bool execute(Script* script, QWebFrame*) {
@ -1937,7 +1967,6 @@ class Function: public Command {
} }
bool call(Command* parentCommand, QStringList args, bool call(Command* parentCommand, QStringList args,
Script* script, QWebFrame* frame) { Script* script, QWebFrame* frame) {
Logger log(this, script);
try { try {
return runScript(parentCommand, _script, script, frame, _vars, args); return runScript(parentCommand, _script, script, frame, _vars, args);
} catch (const std::exception& x) { } catch (const std::exception& x) {
@ -1968,7 +1997,7 @@ class Call: public Command {
return tag()+" "+_name+(_args.size()?" '"+_args.join("', '")+"'":""); return tag()+" "+_name+(_args.size()?" '"+_args.join("', '")+"'":"");
} }
std::shared_ptr<Command> parse(Script*, QString args, std::shared_ptr<Command> parse(Script*, QString args,
QStringList&, QString, int) { QStringList&, QString, int, int) {
std::shared_ptr<Call> cmd(new Call()); std::shared_ptr<Call> cmd(new Call());
if (!args.size()) throw BadArgument(tag()+" requires a <name>"); if (!args.size()) throw BadArgument(tag()+" requires a <name>");
QStringList allargs(args.split(" ", QString::SkipEmptyParts)); QStringList allargs(args.split(" ", QString::SkipEmptyParts));
@ -2013,7 +2042,8 @@ class If: public Command {
+(_script.get()?"\n"+_script->print().join("\n "):""); +(_script.get()?"\n"+_script->print().join("\n "):"");
} }
std::shared_ptr<Command> parse(Script*, QString args, std::shared_ptr<Command> parse(Script*, QString args,
QStringList& in, QString file, int line) { QStringList& in, QString file, int line,
int indent) {
std::shared_ptr<If> cmd(new If()); std::shared_ptr<If> cmd(new If());
int pos(args.indexOf(QRegularExpression("[=^~<>]"))); int pos(args.indexOf(QRegularExpression("[=^~<>]")));
if (pos<0) throw BadArgument(tag()+" needs a comparision, not: "+args); if (pos<0) throw BadArgument(tag()+" needs a comparision, not: "+args);
@ -2021,11 +2051,11 @@ class If: public Command {
cmd->_cmp = args[pos].toLatin1(); cmd->_cmp = args[pos].toLatin1();
cmd->_value = args.mid(pos+1).trimmed(); cmd->_value = args.mid(pos+1).trimmed();
cmd->_script = std::shared_ptr<Script>(new Script); cmd->_script = std::shared_ptr<Script>(new Script);
cmd->_script->parse(subCommandBlock(in), file, line+1); cmd->_script->parse(subCommandBlock(in), file, line+1, indent+1);
if (in.size() && in.first().contains(QRegularExpression("^else *$"))) { if (in.size() && in.first().contains(QRegularExpression("^else *$"))) {
in.removeFirst(); in.removeFirst();
cmd->_else = std::shared_ptr<Script>(new Script); cmd->_else = std::shared_ptr<Script>(new Script);
cmd->_else->parse(subCommandBlock(in), file, line+1); cmd->_else->parse(subCommandBlock(in), file, line+1, indent+1);
} }
return cmd; return cmd;
} }
@ -2047,6 +2077,8 @@ class If: public Command {
break; break;
default:; default:;
} }
log("evaluated expression: "+script->variable(_variable)
+" "+_cmp+" "+value);
if (check) return runScript(this, _script, script, frame); if (check) return runScript(this, _script, script, frame);
else if (_else) return runScript(this, _else, script, frame); else if (_else) return runScript(this, _else, script, frame);
return true; return true;
@ -2074,7 +2106,7 @@ class TestSuite: public Command {
return tag()+" "+_name; return tag()+" "+_name;
} }
std::shared_ptr<Command> parse(Script*, QString args, std::shared_ptr<Command> parse(Script*, QString args,
QStringList&, QString, int) { QStringList&, QString, int, int) {
std::shared_ptr<TestSuite> cmd(new TestSuite()); std::shared_ptr<TestSuite> cmd(new TestSuite());
cmd->_name = args; cmd->_name = args;
return cmd; return cmd;
@ -2103,7 +2135,7 @@ class TestCase: public Command {
return tag()+" "+_name; return tag()+" "+_name;
} }
std::shared_ptr<Command> parse(Script*, QString args, std::shared_ptr<Command> parse(Script*, QString args,
QStringList&, QString, int) { QStringList&, QString, int, int) {
std::shared_ptr<TestCase> cmd(new TestCase()); std::shared_ptr<TestCase> cmd(new TestCase());
cmd->_name = args; cmd->_name = args;
return cmd; return cmd;
@ -2141,7 +2173,8 @@ class Check: public Command {
return tag()+" "+_value1+" "+QString(_cmp)+" "+_value2; return tag()+" "+_value1+" "+QString(_cmp)+" "+_value2;
} }
std::shared_ptr<Command> parse(Script* script, QString args, std::shared_ptr<Command> parse(Script* script, QString args,
QStringList& in, QString file, int line) { QStringList& in, QString file, int line,
int indent) {
std::shared_ptr<Check> cmd(new Check()); std::shared_ptr<Check> cmd(new Check());
cmd->_next = 0; cmd->_next = 0;
int pos(args.indexOf(QRegularExpression("[=^~<>]"))); int pos(args.indexOf(QRegularExpression("[=^~<>]")));
@ -2150,7 +2183,7 @@ class Check: public Command {
cmd->_cmp = args[pos].toLatin1(); cmd->_cmp = args[pos].toLatin1();
cmd->_value2 = args.mid(pos+1).trimmed(); cmd->_value2 = args.mid(pos+1).trimmed();
if (in.size() && in.first().contains(QRegularExpression("^ "))) { if (in.size() && in.first().contains(QRegularExpression("^ "))) {
cmd->_next = script->parseLine(in, file, line+1); cmd->_next = script->parseLine(in, file, line+1, indent+1);
cmd->_next->log(false); // suppress logging of subcommand cmd->_next->log(false); // suppress logging of subcommand
} }
return cmd; return cmd;
@ -2172,6 +2205,7 @@ class Check: public Command {
case '>': check = value1.toInt()>value2.toInt(); break; case '>': check = value1.toInt()>value2.toInt(); break;
default:; default:;
} }
log("evaluated expression: "+value1+" "+_cmp+" "+value2);
if (!check) throw CheckFailed(value1, _cmp, value2); if (!check) throw CheckFailed(value1, _cmp, value2);
return true; return true;
} }
@ -2198,7 +2232,7 @@ class : public Command {
return tag(); return tag();
} }
std::shared_ptr<Command> parse(Script*, QString args, std::shared_ptr<Command> parse(Script*, QString args,
QStringList&, QString, int) { QStringList&, QString, int, int) {
std::shared_ptr<> cmd(new ()); std::shared_ptr<> cmd(new ());
return cmd; return cmd;
} }
@ -2221,30 +2255,19 @@ inline bool Screenshot::execute(Script* script, QWebFrame* frame) {
inline Logger::Logger(Command* command, Script* script): inline Logger::Logger(Command* command, Script* script):
_command(command), _script(script) { _command(command), _script(script) {
if (_command->log()) { _previous = _script->command();
_script->log(QString _script->command(command);
("%1:%2 \\ %3") if (_command->log()) _script->log("\\ "+_command->command(), _command);
.arg(_command->file()).arg(_command->line())
.arg(_command->command()));
}
} }
inline void Logger::operator()(QString txt) { inline void Logger::operator()(QString txt) {
if (_command->log()) if (_command->log()) _script->log(" "+txt, _command);
_script->log(QString
("%1:%2 %3")
.arg(_command->file()).arg(_command->line())
.arg(txt));
} }
inline void Logger::operator[](QString txt) { inline void Logger::operator[](QString txt) {
_script->plainlog(txt); _script->plainlog(txt);
} }
inline Logger::~Logger() { inline Logger::~Logger() {
if (_command->log()) { if (_command->log()) _script->log("/ "+_command->command(), _command);
_script->log(QString _script->command(_previous);
("%1:%2 / %3")
.arg(_command->file()).arg(_command->line())
.arg(_command->command()));
}
} }
inline bool Command::runScript(Command* parentCommand, inline bool Command::runScript(Command* parentCommand,
@ -2268,6 +2291,8 @@ inline bool Command::runScript(Command* parentCommand,
disconnect(&scriptCopy, SIGNAL(logging(QString)), disconnect(&scriptCopy, SIGNAL(logging(QString)),
parent, SLOT(parentlog(QString))); parent, SLOT(parentlog(QString)));
parentCommand->_result = scriptCopy.result(); parentCommand->_result = scriptCopy.result();
if (parentCommand->_result.size())
parent->log("result: "+parentCommand->_result);
return res; return res;
} catch (const std::exception& x) { } catch (const std::exception& x) {
parent->addSignals(frame); parent->addSignals(frame);

Loading…
Cancel
Save