|
|
|
@ -93,7 +93,7 @@ class Command: public QObject { |
|
|
|
|
virtual QString description() const = 0; |
|
|
|
|
virtual QString command() const = 0; |
|
|
|
|
virtual std::shared_ptr<Command> parse(Script*, QString, |
|
|
|
|
QStringList&, int) = 0; |
|
|
|
|
QStringList&, QString, int) = 0; |
|
|
|
|
virtual bool execute(Script*, QWebFrame*) = 0; |
|
|
|
|
void line(int linenr) { |
|
|
|
|
_line = linenr; |
|
|
|
@ -101,6 +101,12 @@ class Command: public QObject { |
|
|
|
|
int line() const { |
|
|
|
|
return _line; |
|
|
|
|
} |
|
|
|
|
void file(QString filename) { |
|
|
|
|
_file = filename; |
|
|
|
|
} |
|
|
|
|
QString file() const { |
|
|
|
|
return _file; |
|
|
|
|
} |
|
|
|
|
bool log() { |
|
|
|
|
return _log; |
|
|
|
|
} |
|
|
|
@ -170,10 +176,12 @@ class Command: public QObject { |
|
|
|
|
case '"': case '\'': { |
|
|
|
|
return value.mid(1, value.size()-2) |
|
|
|
|
.split(QRegularExpression(QString(value[0])+", *" |
|
|
|
|
+QString(value[0]))); |
|
|
|
|
+QString(value[0])), |
|
|
|
|
QString::SkipEmptyParts); |
|
|
|
|
} break; |
|
|
|
|
default: { |
|
|
|
|
return value.split(QRegularExpression(", *")); |
|
|
|
|
return value.split(QRegularExpression(", *"), |
|
|
|
|
QString::SkipEmptyParts); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -210,6 +218,7 @@ class Command: public QObject { |
|
|
|
|
QString _result; |
|
|
|
|
private: |
|
|
|
|
int _line; |
|
|
|
|
QString _file; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
class Empty: public Command { |
|
|
|
@ -226,7 +235,8 @@ class Empty: public Command { |
|
|
|
|
QString command() const { |
|
|
|
|
return tag(); |
|
|
|
|
} |
|
|
|
|
std::shared_ptr<Command> parse(Script*, QString, QStringList&, int) { |
|
|
|
|
std::shared_ptr<Command> parse(Script*, QString, |
|
|
|
|
QStringList&, QString, int) { |
|
|
|
|
std::shared_ptr<Empty> cmd(new Empty()); |
|
|
|
|
return cmd; |
|
|
|
|
} |
|
|
|
@ -237,7 +247,7 @@ class Empty: public Command { |
|
|
|
|
|
|
|
|
|
class Comment: public Command { |
|
|
|
|
public: |
|
|
|
|
Comment(QString line): _line(line) {} |
|
|
|
|
Comment(QString comment): _comment(comment) {} |
|
|
|
|
QString tag() const { |
|
|
|
|
return "#"; |
|
|
|
|
} |
|
|
|
@ -248,9 +258,10 @@ class Comment: public Command { |
|
|
|
|
"Comments are lines that start with #"; |
|
|
|
|
} |
|
|
|
|
QString command() const { |
|
|
|
|
return _line; |
|
|
|
|
return _comment; |
|
|
|
|
} |
|
|
|
|
std::shared_ptr<Command> parse(Script*, QString args, QStringList&, int) { |
|
|
|
|
std::shared_ptr<Command> parse(Script*, QString args, |
|
|
|
|
QStringList&, QString, int) { |
|
|
|
|
std::shared_ptr<Comment> cmd(new Comment(args)); |
|
|
|
|
return cmd; |
|
|
|
|
} |
|
|
|
@ -259,7 +270,7 @@ class Comment: public Command { |
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
private: |
|
|
|
|
QString _line; |
|
|
|
|
QString _comment; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
class Screenshot: public Command { |
|
|
|
@ -321,7 +332,8 @@ class Screenshot: public Command { |
|
|
|
|
QString command() const { |
|
|
|
|
return tag()+" "+_filename; |
|
|
|
|
} |
|
|
|
|
std::shared_ptr<Command> parse(Script*, QString args, QStringList&, int) { |
|
|
|
|
std::shared_ptr<Command> parse(Script*, QString args, |
|
|
|
|
QStringList&, QString, int) { |
|
|
|
|
std::shared_ptr<Screenshot> cmd(new Screenshot()); |
|
|
|
|
cmd->_filename = args; |
|
|
|
|
return cmd; |
|
|
|
@ -399,6 +411,12 @@ class Script: public QObject { |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
public: |
|
|
|
|
Script(const Script& o): |
|
|
|
|
QObject(), |
|
|
|
|
_prototypes(o._prototypes), |
|
|
|
|
_script(o._script) { |
|
|
|
|
set(o); |
|
|
|
|
} |
|
|
|
|
static QString xmlattr(QString attr, bool br = false) { |
|
|
|
|
attr.replace("&", "&")//.replace(" ", " ")
|
|
|
|
|
.replace("\"", """); |
|
|
|
@ -475,7 +493,9 @@ class Script: public QObject { |
|
|
|
|
_timeout = 20; |
|
|
|
|
_clicktype = JAVASCRIPT_CLICK; |
|
|
|
|
} |
|
|
|
|
std::shared_ptr<Command> parse(QStringList& in, int linenr) try { |
|
|
|
|
std::shared_ptr<Command> parseLine(QStringList& in, |
|
|
|
|
QString filename, int linenr) try { |
|
|
|
|
std::shared_ptr<Command> command; |
|
|
|
|
QString line(in.takeFirst().trimmed()); |
|
|
|
|
QString cmd(line), args; |
|
|
|
|
int space(line.indexOf(' ')); |
|
|
|
@ -485,22 +505,23 @@ class Script: public QObject { |
|
|
|
|
} |
|
|
|
|
Prototypes::const_iterator it(_prototypes.find(cmd)); |
|
|
|
|
if (it!=_prototypes.end()) { |
|
|
|
|
std::shared_ptr<Command> command(it->second->parse |
|
|
|
|
(this, args, in, linenr)); |
|
|
|
|
command->line(linenr); |
|
|
|
|
return command; |
|
|
|
|
command = it->second->parse(this, args, in, filename, linenr); |
|
|
|
|
} else { |
|
|
|
|
return unknown(line); |
|
|
|
|
command = unknown(line); |
|
|
|
|
} |
|
|
|
|
command->file(filename); |
|
|
|
|
command->line(linenr); |
|
|
|
|
return command; |
|
|
|
|
} catch (Exception& e) { |
|
|
|
|
e.line(linenr); |
|
|
|
|
e.file(filename); |
|
|
|
|
throw; |
|
|
|
|
} |
|
|
|
|
void parse(QStringList in) { |
|
|
|
|
for (int linenr(1), oldsize(0); |
|
|
|
|
void parse(QStringList in, QString filename, int line = 1) { |
|
|
|
|
for (int linenr(0), oldsize(0); |
|
|
|
|
oldsize=in.size(), in.size(); |
|
|
|
|
linenr+=oldsize-in.size()) |
|
|
|
|
_script.push_back(parse(in, linenr)); |
|
|
|
|
_script.push_back(parseLine(in, filename, line+linenr)); |
|
|
|
|
} |
|
|
|
|
QStringList print() { |
|
|
|
|
QStringList result; |
|
|
|
@ -628,6 +649,7 @@ class Script: public QObject { |
|
|
|
|
_testsuites->last()<<testcase; |
|
|
|
|
removeSignals(frame); |
|
|
|
|
e.line((*cmd)->line()); |
|
|
|
|
e.file((*cmd)->file()); |
|
|
|
|
if (screenshots) |
|
|
|
|
try { // write html source and take a last screenshot on error
|
|
|
|
|
{ |
|
|
|
@ -721,7 +743,7 @@ class Script: public QObject { |
|
|
|
|
_cout.clear(); |
|
|
|
|
_cerr.clear(); |
|
|
|
|
_ignoreSignalsUntil.clear(); |
|
|
|
|
_functions.clear(); |
|
|
|
|
_functions.unite(o._functions); |
|
|
|
|
} |
|
|
|
|
void unset(QString name) { |
|
|
|
|
_rvariables.remove(_variables[name]); |
|
|
|
@ -824,11 +846,17 @@ class Script: public QObject { |
|
|
|
|
std::cout<<text<<std::endl<<std::flush; |
|
|
|
|
_cout += text + "\n"; |
|
|
|
|
} |
|
|
|
|
void parentlog(QString text) { |
|
|
|
|
logging(text); |
|
|
|
|
_cout += text + "\n"; |
|
|
|
|
} |
|
|
|
|
private: |
|
|
|
|
std::shared_ptr<Command> unknown(QString line) { |
|
|
|
|
if (!line.size()) return std::shared_ptr<Command>(new Empty()); |
|
|
|
|
if (line[0]=='#') return std::shared_ptr<Command>(new Comment(line)); |
|
|
|
|
throw UnknownCommand(line); // error
|
|
|
|
|
std::shared_ptr<Command> unknown(QString command) { |
|
|
|
|
if (!command.size()) |
|
|
|
|
return std::shared_ptr<Command>(new Empty()); |
|
|
|
|
if (command[0]=='#') |
|
|
|
|
return std::shared_ptr<Command>(new Comment(command)); |
|
|
|
|
throw UnknownCommand(command); // error
|
|
|
|
|
} |
|
|
|
|
void initPrototypes(); |
|
|
|
|
void add(Command* c) { |
|
|
|
@ -851,9 +879,7 @@ class Script: public QObject { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
_ignoreSignalsUntil.clear(); |
|
|
|
|
log(".... signal"); |
|
|
|
|
log("received loadFinished "+QString(ok?"true":"false")); |
|
|
|
|
log("....................."); |
|
|
|
|
log("signal received: loadFinished "+QString(ok?"true":"false")); |
|
|
|
|
_signals.push(std::make_pair("loadFinished", QStringList(sig))); |
|
|
|
|
} |
|
|
|
|
void loadStarted() { |
|
|
|
@ -862,9 +888,7 @@ class Script: public QObject { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
_ignoreSignalsUntil.clear(); |
|
|
|
|
log(".... signal"); |
|
|
|
|
log("received loadStarted"); |
|
|
|
|
log("....................."); |
|
|
|
|
log("signal received: loadStarted"); |
|
|
|
|
_signals.push(std::make_pair("loadStarted", QStringList())); |
|
|
|
|
} |
|
|
|
|
void frameChanged() { |
|
|
|
@ -878,9 +902,7 @@ class Script: public QObject { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
_ignoreSignalsUntil.clear(); |
|
|
|
|
log(".... signal"); |
|
|
|
|
log("received urlChanged "+url.toString()); |
|
|
|
|
log("....................."); |
|
|
|
|
log("signal received: urlChanged "+url.toString()); |
|
|
|
|
_signals.push(std::make_pair("urlChanged", |
|
|
|
|
QStringList(url.toString()))); |
|
|
|
|
} |
|
|
|
@ -929,7 +951,7 @@ class Do: public Command { |
|
|
|
|
return tag()+" "+_selector+_javascript; |
|
|
|
|
} |
|
|
|
|
std::shared_ptr<Command> parse(Script*, QString args, |
|
|
|
|
QStringList& in, int) { |
|
|
|
|
QStringList& in, QString, int) { |
|
|
|
|
std::shared_ptr<Do> cmd(new Do()); |
|
|
|
|
cmd->_selector = args.trimmed(); |
|
|
|
|
cmd->_javascript = subCommandBlock(in).join("\n"); |
|
|
|
@ -966,7 +988,8 @@ class Load: public Command { |
|
|
|
|
QString command() const { |
|
|
|
|
return tag()+" "+_url; |
|
|
|
|
} |
|
|
|
|
std::shared_ptr<Command> parse(Script*, QString args, QStringList&, int) { |
|
|
|
|
std::shared_ptr<Command> parse(Script*, QString args, |
|
|
|
|
QStringList&, QString, int) { |
|
|
|
|
std::shared_ptr<Load> cmd(new Load()); |
|
|
|
|
cmd->_url = args; |
|
|
|
|
return cmd; |
|
|
|
@ -1009,7 +1032,8 @@ class Expect: public Command { |
|
|
|
|
return tag()+" "+_signal._signal |
|
|
|
|
+(_signal._args.size()?" "+_signal._args.join(' '):QString()); |
|
|
|
|
} |
|
|
|
|
std::shared_ptr<Command> parse(Script*, QString args, QStringList&, int) { |
|
|
|
|
std::shared_ptr<Command> parse(Script*, QString args, |
|
|
|
|
QStringList&, QString, int) { |
|
|
|
|
std::shared_ptr<Expect> cmd(new Expect()); |
|
|
|
|
cmd->_signal._args = args.split(" "); |
|
|
|
|
cmd->_signal._signal = cmd->_signal._args.takeFirst(); |
|
|
|
@ -1064,7 +1088,8 @@ class Open: public Command { |
|
|
|
|
QString command() const { |
|
|
|
|
return tag(); |
|
|
|
|
} |
|
|
|
|
std::shared_ptr<Command> parse(Script*, QString, QStringList&, int) { |
|
|
|
|
std::shared_ptr<Command> parse(Script*, QString, |
|
|
|
|
QStringList&, QString, int) { |
|
|
|
|
std::shared_ptr<Open> cmd(new Open()); |
|
|
|
|
return cmd; |
|
|
|
|
} |
|
|
|
@ -1091,7 +1116,8 @@ class Sleep: public Command { |
|
|
|
|
QString command() const { |
|
|
|
|
return tag()+" "+_time; |
|
|
|
|
} |
|
|
|
|
std::shared_ptr<Command> parse(Script*, QString time, QStringList&, int) { |
|
|
|
|
std::shared_ptr<Command> parse(Script*, QString time, |
|
|
|
|
QStringList&, QString, int) { |
|
|
|
|
std::shared_ptr<Sleep> cmd(new Sleep()); |
|
|
|
|
cmd->_time = "10"; // default: 10s
|
|
|
|
|
if (time.size()) cmd->_time = time; |
|
|
|
@ -1128,7 +1154,8 @@ class Exit: public Command { |
|
|
|
|
QString command() const { |
|
|
|
|
return tag(); |
|
|
|
|
} |
|
|
|
|
std::shared_ptr<Command> parse(Script*, QString, QStringList&, int) { |
|
|
|
|
std::shared_ptr<Command> parse(Script*, QString, |
|
|
|
|
QStringList&, QString, int) { |
|
|
|
|
std::shared_ptr<Exit> cmd(new Exit()); |
|
|
|
|
return cmd; |
|
|
|
|
} |
|
|
|
@ -1155,7 +1182,8 @@ class IgnoreTo: public Command { |
|
|
|
|
QString command() const { |
|
|
|
|
return tag()+" "+_label; |
|
|
|
|
} |
|
|
|
|
std::shared_ptr<Command> parse(Script*, QString args, QStringList&, int) { |
|
|
|
|
std::shared_ptr<Command> parse(Script*, QString args, |
|
|
|
|
QStringList&, QString, int) { |
|
|
|
|
std::shared_ptr<IgnoreTo> cmd(new IgnoreTo()); |
|
|
|
|
if (!args.size()) throw BadArgument("ignoreto needs a label"); |
|
|
|
|
cmd->_label=args; |
|
|
|
@ -1184,7 +1212,8 @@ class Label: public Command { |
|
|
|
|
QString command() const { |
|
|
|
|
return tag()+" "+_label; |
|
|
|
|
} |
|
|
|
|
std::shared_ptr<Command> parse(Script*, QString args, QStringList&, int) { |
|
|
|
|
std::shared_ptr<Command> parse(Script*, QString args, |
|
|
|
|
QStringList&, QString, int) { |
|
|
|
|
std::shared_ptr<Label> cmd(new Label()); |
|
|
|
|
if (!args.size()) throw BadArgument("label needs a label as parameter"); |
|
|
|
|
cmd->_label=args; |
|
|
|
@ -1215,7 +1244,8 @@ class Upload: public Command { |
|
|
|
|
QString command() const { |
|
|
|
|
return tag()+" "+_selector+" -> "+_filename; |
|
|
|
|
} |
|
|
|
|
std::shared_ptr<Command> parse(Script*, QString args, QStringList&, int) { |
|
|
|
|
std::shared_ptr<Command> parse(Script*, QString args, |
|
|
|
|
QStringList&, QString, int) { |
|
|
|
|
std::shared_ptr<Upload> cmd(new Upload()); |
|
|
|
|
QStringList allargs(args.split("->")); |
|
|
|
|
if (allargs.size()<2) |
|
|
|
@ -1263,7 +1293,8 @@ class Exists: public Command { |
|
|
|
|
QString command() const { |
|
|
|
|
return tag()+" "+_selector+(_text.size()?" -> "+_text:QString()); |
|
|
|
|
} |
|
|
|
|
std::shared_ptr<Command> parse(Script*, QString args, QStringList&, int) { |
|
|
|
|
std::shared_ptr<Command> parse(Script*, QString args, |
|
|
|
|
QStringList&, QString, int) { |
|
|
|
|
std::shared_ptr<Exists> cmd(new Exists()); |
|
|
|
|
QStringList allargs(args.split("->")); |
|
|
|
|
if (allargs.size()<2) { |
|
|
|
@ -1315,7 +1346,8 @@ class Not: public Command { |
|
|
|
|
QString command() const { |
|
|
|
|
return tag()+" "+_selector+(_text.size()?" -> "+_text:QString()); |
|
|
|
|
} |
|
|
|
|
std::shared_ptr<Command> parse(Script*, QString args, QStringList&, int) { |
|
|
|
|
std::shared_ptr<Command> parse(Script*, QString args, |
|
|
|
|
QStringList&, QString, int) { |
|
|
|
|
std::shared_ptr<Not> cmd(new Not()); |
|
|
|
|
QStringList allargs(args.split("->")); |
|
|
|
|
if (allargs.size()<2) { |
|
|
|
@ -1366,7 +1398,7 @@ class Execute: public Command { |
|
|
|
|
+(script.size()?"\n"+script.join("\n"):QString()); |
|
|
|
|
} |
|
|
|
|
std::shared_ptr<Command> parse(Script*, QString args, |
|
|
|
|
QStringList& in, int) { |
|
|
|
|
QStringList& in, QString, int) { |
|
|
|
|
std::shared_ptr<Execute> cmd(new Execute()); |
|
|
|
|
cmd->_args = args.split(' '); |
|
|
|
|
cmd->_command = cmd->_args.takeFirst(); |
|
|
|
@ -1429,10 +1461,10 @@ class Download: public Command { |
|
|
|
|
+_next->command(); |
|
|
|
|
} |
|
|
|
|
std::shared_ptr<Command> parse(Script* script, QString args, |
|
|
|
|
QStringList& in, int line) { |
|
|
|
|
QStringList& in, QString file, int line) { |
|
|
|
|
std::shared_ptr<Download> cmd(new Download()); |
|
|
|
|
cmd->_filename = args.trimmed(); |
|
|
|
|
cmd->_next = script->parse(in, line+1); |
|
|
|
|
cmd->_next = script->parseLine(in, file, line+1); |
|
|
|
|
cmd->_next->log(false); // suppress logging of subcommand
|
|
|
|
|
return cmd; |
|
|
|
|
} |
|
|
|
@ -1508,7 +1540,8 @@ class Click: public Command { |
|
|
|
|
:*_clicktype==Script::JAVASCRIPT_CLICK?" javascript":"") |
|
|
|
|
:"")+" "+_selector; |
|
|
|
|
} |
|
|
|
|
std::shared_ptr<Command> parse(Script*, QString args, QStringList&, int) { |
|
|
|
|
std::shared_ptr<Command> parse(Script*, QString args, |
|
|
|
|
QStringList&, QString, int) { |
|
|
|
|
std::shared_ptr<Click> cmd(new Click()); |
|
|
|
|
if (args.trimmed().contains(QRegularExpression("^realmouse "))) |
|
|
|
|
cmd->_clicktype = Script::REAL_MOUSE_CLICK; |
|
|
|
@ -1569,14 +1602,14 @@ class Set: public Command { |
|
|
|
|
return tag()+" "+_name+" = "+_value; |
|
|
|
|
} |
|
|
|
|
std::shared_ptr<Command> parse(Script* script, QString args, |
|
|
|
|
QStringList& in, int line) { |
|
|
|
|
QStringList& in, QString file, int line) { |
|
|
|
|
std::shared_ptr<Set> cmd(new Set()); |
|
|
|
|
cmd->_next = 0; |
|
|
|
|
QStringList allargs(args.split("=")); |
|
|
|
|
cmd->_name = allargs.takeFirst().trimmed(); |
|
|
|
|
cmd->_value = allargs.join("=").trimmed(); |
|
|
|
|
if (!args.contains('=')) { |
|
|
|
|
cmd->_next = script->parse(in, line+1); |
|
|
|
|
cmd->_next = script->parseLine(in, file, line+1); |
|
|
|
|
cmd->_next->log(false); // suppress logging of subcommand
|
|
|
|
|
} |
|
|
|
|
return cmd; |
|
|
|
@ -1614,7 +1647,7 @@ class UnSet: public Command { |
|
|
|
|
return tag()+" "+_name; |
|
|
|
|
} |
|
|
|
|
std::shared_ptr<Command> parse(Script*, QString args, |
|
|
|
|
QStringList&, int) { |
|
|
|
|
QStringList&, QString, int) { |
|
|
|
|
std::shared_ptr<UnSet> cmd(new UnSet()); |
|
|
|
|
cmd->_name = args; |
|
|
|
|
return cmd; |
|
|
|
@ -1643,7 +1676,7 @@ class Timeout: public Command { |
|
|
|
|
return tag()+" "+_timeout; |
|
|
|
|
} |
|
|
|
|
std::shared_ptr<Command> parse(Script*, QString args, |
|
|
|
|
QStringList&, int) { |
|
|
|
|
QStringList&, QString, int) { |
|
|
|
|
std::shared_ptr<Timeout> cmd(new Timeout()); |
|
|
|
|
cmd->_timeout = args; |
|
|
|
|
return cmd; |
|
|
|
@ -1676,7 +1709,7 @@ class CaCertificate: public Command { |
|
|
|
|
return tag()+" "+_filename; |
|
|
|
|
} |
|
|
|
|
std::shared_ptr<Command> parse(Script*, QString args, |
|
|
|
|
QStringList&, int) { |
|
|
|
|
QStringList&, QString, int) { |
|
|
|
|
std::shared_ptr<CaCertificate> cmd(new (CaCertificate)); |
|
|
|
|
cmd->_filename = args.trimmed(); |
|
|
|
|
return cmd; |
|
|
|
@ -1715,7 +1748,7 @@ class ClientCertificate: public Command { |
|
|
|
|
return tag()+" "+_certfile+" "+_keyfile+" "+_password; |
|
|
|
|
} |
|
|
|
|
std::shared_ptr<Command> parse(Script*, QString args, |
|
|
|
|
QStringList&, int) { |
|
|
|
|
QStringList&, QString, int) { |
|
|
|
|
std::shared_ptr<ClientCertificate> cmd(new (ClientCertificate)); |
|
|
|
|
QStringList s(args.trimmed().split(' ')); |
|
|
|
|
if (s.size()<3) throw MissingArguments(args, "certfile keyfile password"); |
|
|
|
@ -1779,7 +1812,7 @@ class ClickType: public Command { |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
std::shared_ptr<Command> parse(Script* script, QString args, |
|
|
|
|
QStringList&, int) { |
|
|
|
|
QStringList&, QString, int) { |
|
|
|
|
std::shared_ptr<ClickType> cmd(new ClickType()); |
|
|
|
|
QString choice(script->replacevars(args).trimmed()); |
|
|
|
|
if (choice=="realmouse") |
|
|
|
@ -1823,7 +1856,7 @@ class SetValue: public Command { |
|
|
|
|
return tag()+" "+_selector+" -> "+_value; |
|
|
|
|
} |
|
|
|
|
std::shared_ptr<Command> parse(Script*, QString args, |
|
|
|
|
QStringList&, int) { |
|
|
|
|
QStringList&, QString, int) { |
|
|
|
|
std::shared_ptr<SetValue> cmd(new SetValue()); |
|
|
|
|
QStringList allargs(args.split("->")); |
|
|
|
|
if (allargs.size()<2) |
|
|
|
@ -1887,15 +1920,15 @@ class Function: public Command { |
|
|
|
|
return tag()+" "+_name+" "+_vars.join(" "); |
|
|
|
|
} |
|
|
|
|
std::shared_ptr<Command> parse(Script* script, QString args, |
|
|
|
|
QStringList& in, int) { |
|
|
|
|
QStringList& in, QString file, int line) { |
|
|
|
|
std::shared_ptr<Function> cmd(new Function()); |
|
|
|
|
if (!args.size()) throw BadArgument(tag()+" requires a <name>"); |
|
|
|
|
QStringList allargs(args.split(" ")); |
|
|
|
|
QStringList allargs(args.split(" ", QString::SkipEmptyParts)); |
|
|
|
|
cmd->_name = allargs.takeFirst().trimmed(); |
|
|
|
|
cmd->_vars = commaSeparatedList(allargs.join(' ')); |
|
|
|
|
script->function(cmd->_name, cmd); |
|
|
|
|
cmd->_script = std::shared_ptr<Script>(new Script); |
|
|
|
|
cmd->_script->parse(subCommandBlock(in)); |
|
|
|
|
cmd->_script->parse(subCommandBlock(in), file, line+1); |
|
|
|
|
return cmd; |
|
|
|
|
} |
|
|
|
|
bool execute(Script* script, QWebFrame*) { |
|
|
|
@ -1935,10 +1968,10 @@ class Call: public Command { |
|
|
|
|
return tag()+" "+_name+(_args.size()?" '"+_args.join("', '")+"'":""); |
|
|
|
|
} |
|
|
|
|
std::shared_ptr<Command> parse(Script*, QString args, |
|
|
|
|
QStringList&, int) { |
|
|
|
|
QStringList&, QString, int) { |
|
|
|
|
std::shared_ptr<Call> cmd(new Call()); |
|
|
|
|
if (!args.size()) throw BadArgument(tag()+" requires a <name>"); |
|
|
|
|
QStringList allargs(args.split(" ")); |
|
|
|
|
QStringList allargs(args.split(" ", QString::SkipEmptyParts)); |
|
|
|
|
cmd->_name = allargs.takeFirst().trimmed(); |
|
|
|
|
cmd->_args = commaSeparatedList(allargs.join(' ')); |
|
|
|
|
return cmd; |
|
|
|
@ -1980,7 +2013,7 @@ class If: public Command { |
|
|
|
|
+(_script.get()?"\n"+_script->print().join("\n "):""); |
|
|
|
|
} |
|
|
|
|
std::shared_ptr<Command> parse(Script*, QString args, |
|
|
|
|
QStringList& in, int) { |
|
|
|
|
QStringList& in, QString file, int line) { |
|
|
|
|
std::shared_ptr<If> cmd(new If()); |
|
|
|
|
int pos(args.indexOf(QRegularExpression("[=^~<>]"))); |
|
|
|
|
if (pos<0) throw BadArgument(tag()+" needs a comparision, not: "+args); |
|
|
|
@ -1988,11 +2021,11 @@ class If: public Command { |
|
|
|
|
cmd->_cmp = args[pos].toLatin1(); |
|
|
|
|
cmd->_value = args.mid(pos+1).trimmed(); |
|
|
|
|
cmd->_script = std::shared_ptr<Script>(new Script); |
|
|
|
|
cmd->_script->parse(subCommandBlock(in)); |
|
|
|
|
cmd->_script->parse(subCommandBlock(in), file, line+1); |
|
|
|
|
if (in.size() && in.first().contains(QRegularExpression("^else *$"))) { |
|
|
|
|
in.removeFirst(); |
|
|
|
|
cmd->_else = std::shared_ptr<Script>(new Script); |
|
|
|
|
cmd->_else->parse(subCommandBlock(in)); |
|
|
|
|
cmd->_else->parse(subCommandBlock(in), file, line+1); |
|
|
|
|
} |
|
|
|
|
return cmd; |
|
|
|
|
} |
|
|
|
@ -2041,7 +2074,7 @@ class TestSuite: public Command { |
|
|
|
|
return tag()+" "+_name; |
|
|
|
|
} |
|
|
|
|
std::shared_ptr<Command> parse(Script*, QString args, |
|
|
|
|
QStringList&, int) { |
|
|
|
|
QStringList&, QString, int) { |
|
|
|
|
std::shared_ptr<TestSuite> cmd(new TestSuite()); |
|
|
|
|
cmd->_name = args; |
|
|
|
|
return cmd; |
|
|
|
@ -2070,7 +2103,7 @@ class TestCase: public Command { |
|
|
|
|
return tag()+" "+_name; |
|
|
|
|
} |
|
|
|
|
std::shared_ptr<Command> parse(Script*, QString args, |
|
|
|
|
QStringList&, int) { |
|
|
|
|
QStringList&, QString, int) { |
|
|
|
|
std::shared_ptr<TestCase> cmd(new TestCase()); |
|
|
|
|
cmd->_name = args; |
|
|
|
|
return cmd; |
|
|
|
@ -2108,7 +2141,7 @@ class Check: public Command { |
|
|
|
|
return tag()+" "+_value1+" "+QString(_cmp)+" "+_value2; |
|
|
|
|
} |
|
|
|
|
std::shared_ptr<Command> parse(Script* script, QString args, |
|
|
|
|
QStringList& in, int line) { |
|
|
|
|
QStringList& in, QString file, int line) { |
|
|
|
|
std::shared_ptr<Check> cmd(new Check()); |
|
|
|
|
cmd->_next = 0; |
|
|
|
|
int pos(args.indexOf(QRegularExpression("[=^~<>]"))); |
|
|
|
@ -2117,7 +2150,7 @@ class Check: public Command { |
|
|
|
|
cmd->_cmp = args[pos].toLatin1(); |
|
|
|
|
cmd->_value2 = args.mid(pos+1).trimmed(); |
|
|
|
|
if (in.size() && in.first().contains(QRegularExpression("^ "))) { |
|
|
|
|
cmd->_next = script->parse(in, line+1); |
|
|
|
|
cmd->_next = script->parseLine(in, file, line+1); |
|
|
|
|
cmd->_next->log(false); // suppress logging of subcommand
|
|
|
|
|
} |
|
|
|
|
return cmd; |
|
|
|
@ -2165,7 +2198,7 @@ class : public Command { |
|
|
|
|
return tag(); |
|
|
|
|
} |
|
|
|
|
std::shared_ptr<Command> parse(Script*, QString args, |
|
|
|
|
QStringList&, int) { |
|
|
|
|
QStringList&, QString, int) { |
|
|
|
|
std::shared_ptr<> cmd(new ()); |
|
|
|
|
return cmd; |
|
|
|
|
} |
|
|
|
@ -2189,20 +2222,29 @@ inline bool Screenshot::execute(Script* script, QWebFrame* frame) { |
|
|
|
|
inline Logger::Logger(Command* command, Script* script): |
|
|
|
|
_command(command), _script(script) { |
|
|
|
|
if (_command->log()) { |
|
|
|
|
_script->log("---- line: "+QString::number(_command->line())); |
|
|
|
|
_script->log(_command->command()); |
|
|
|
|
_script->log(QString |
|
|
|
|
("%1:%2 \\ %3") |
|
|
|
|
.arg(_command->file()).arg(_command->line()) |
|
|
|
|
.arg(_command->command())); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
inline void Logger::operator()(QString txt) { |
|
|
|
|
if (_command->log()) |
|
|
|
|
_script->log(txt); |
|
|
|
|
_script->log(QString |
|
|
|
|
("%1:%2 %3") |
|
|
|
|
.arg(_command->file()).arg(_command->line()) |
|
|
|
|
.arg(txt)); |
|
|
|
|
} |
|
|
|
|
inline void Logger::operator[](QString txt) { |
|
|
|
|
_script->plainlog(txt); |
|
|
|
|
} |
|
|
|
|
inline Logger::~Logger() { |
|
|
|
|
if (_command->log()) |
|
|
|
|
_script->log("---------------------"); |
|
|
|
|
if (_command->log()) { |
|
|
|
|
_script->log(QString |
|
|
|
|
("%1:%2 / %3") |
|
|
|
|
.arg(_command->file()).arg(_command->line()) |
|
|
|
|
.arg(_command->command())); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
inline bool Command::runScript(Command* parentCommand, |
|
|
|
@ -2210,26 +2252,27 @@ inline bool Command::runScript(Command* parentCommand, |
|
|
|
|
Script* parent, QWebFrame* frame, |
|
|
|
|
QStringList vars, |
|
|
|
|
QStringList args) { |
|
|
|
|
script->set(*parent); |
|
|
|
|
Script scriptCopy(*script); // only work with a copy of script
|
|
|
|
|
scriptCopy.set(*parent); |
|
|
|
|
if (args.size()!=vars.size()) |
|
|
|
|
throw WrongNumberOfArguments(vars, args); |
|
|
|
|
for (QStringList::iterator var(vars.begin()), arg(args.begin()); |
|
|
|
|
var<vars.end() && arg<args.end(); ++var, ++arg) |
|
|
|
|
script->set(*var, parent->replacevars(*arg)); |
|
|
|
|
scriptCopy.set(*var, parent->replacevars(*arg)); |
|
|
|
|
try { |
|
|
|
|
connect(script.get(), SIGNAL(logging(QString)), |
|
|
|
|
parent, SLOT(log(QString))); |
|
|
|
|
connect(&scriptCopy, SIGNAL(logging(QString)), |
|
|
|
|
parent, SLOT(parentlog(QString))); |
|
|
|
|
parent->removeSignals(frame); |
|
|
|
|
bool res(script->run(frame)); |
|
|
|
|
bool res(scriptCopy.run(frame)); |
|
|
|
|
parent->addSignals(frame); |
|
|
|
|
disconnect(script.get(), SIGNAL(logging(QString)), |
|
|
|
|
parent, SLOT(log(QString))); |
|
|
|
|
parentCommand->_result = script->result(); |
|
|
|
|
disconnect(&scriptCopy, SIGNAL(logging(QString)), |
|
|
|
|
parent, SLOT(parentlog(QString))); |
|
|
|
|
parentCommand->_result = scriptCopy.result(); |
|
|
|
|
return res; |
|
|
|
|
} catch (const std::exception& x) { |
|
|
|
|
parent->addSignals(frame); |
|
|
|
|
disconnect(script.get(), SIGNAL(logging(QString)), |
|
|
|
|
parent, SLOT(log(QString))); |
|
|
|
|
disconnect(&scriptCopy, SIGNAL(logging(QString)), |
|
|
|
|
parent, SLOT(parentlog(QString))); |
|
|
|
|
throw; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|