improved logging, bugfix in function handling
This commit is contained in:
209
src/commands.hxx
209
src/commands.hxx
@@ -93,7 +93,7 @@ class Command: public QObject {
|
|||||||
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&, int) = 0;
|
QStringList&, QString, 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;
|
||||||
@@ -101,6 +101,12 @@ class Command: public QObject {
|
|||||||
int line() const {
|
int line() const {
|
||||||
return _line;
|
return _line;
|
||||||
}
|
}
|
||||||
|
void file(QString filename) {
|
||||||
|
_file = filename;
|
||||||
|
}
|
||||||
|
QString file() const {
|
||||||
|
return _file;
|
||||||
|
}
|
||||||
bool log() {
|
bool log() {
|
||||||
return _log;
|
return _log;
|
||||||
}
|
}
|
||||||
@@ -170,10 +176,12 @@ class Command: public QObject {
|
|||||||
case '"': case '\'': {
|
case '"': case '\'': {
|
||||||
return value.mid(1, value.size()-2)
|
return value.mid(1, value.size()-2)
|
||||||
.split(QRegularExpression(QString(value[0])+", *"
|
.split(QRegularExpression(QString(value[0])+", *"
|
||||||
+QString(value[0])));
|
+QString(value[0])),
|
||||||
|
QString::SkipEmptyParts);
|
||||||
} break;
|
} break;
|
||||||
default: {
|
default: {
|
||||||
return value.split(QRegularExpression(", *"));
|
return value.split(QRegularExpression(", *"),
|
||||||
|
QString::SkipEmptyParts);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -210,6 +218,7 @@ class Command: public QObject {
|
|||||||
QString _result;
|
QString _result;
|
||||||
private:
|
private:
|
||||||
int _line;
|
int _line;
|
||||||
|
QString _file;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Empty: public Command {
|
class Empty: public Command {
|
||||||
@@ -226,7 +235,8 @@ class Empty: public Command {
|
|||||||
QString command() const {
|
QString command() const {
|
||||||
return tag();
|
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());
|
std::shared_ptr<Empty> cmd(new Empty());
|
||||||
return cmd;
|
return cmd;
|
||||||
}
|
}
|
||||||
@@ -237,7 +247,7 @@ class Empty: public Command {
|
|||||||
|
|
||||||
class Comment: public Command {
|
class Comment: public Command {
|
||||||
public:
|
public:
|
||||||
Comment(QString line): _line(line) {}
|
Comment(QString comment): _comment(comment) {}
|
||||||
QString tag() const {
|
QString tag() const {
|
||||||
return "#";
|
return "#";
|
||||||
}
|
}
|
||||||
@@ -248,9 +258,10 @@ class Comment: public Command {
|
|||||||
"Comments are lines that start with #";
|
"Comments are lines that start with #";
|
||||||
}
|
}
|
||||||
QString command() const {
|
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));
|
std::shared_ptr<Comment> cmd(new Comment(args));
|
||||||
return cmd;
|
return cmd;
|
||||||
}
|
}
|
||||||
@@ -259,7 +270,7 @@ class Comment: public Command {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
QString _line;
|
QString _comment;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Screenshot: public Command {
|
class Screenshot: public Command {
|
||||||
@@ -321,7 +332,8 @@ class Screenshot: public Command {
|
|||||||
QString command() const {
|
QString command() const {
|
||||||
return tag()+" "+_filename;
|
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());
|
std::shared_ptr<Screenshot> cmd(new Screenshot());
|
||||||
cmd->_filename = args;
|
cmd->_filename = args;
|
||||||
return cmd;
|
return cmd;
|
||||||
@@ -399,6 +411,12 @@ 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("&", "&")//.replace(" ", " ")
|
attr.replace("&", "&")//.replace(" ", " ")
|
||||||
.replace("\"", """);
|
.replace("\"", """);
|
||||||
@@ -475,7 +493,9 @@ class Script: public QObject {
|
|||||||
_timeout = 20;
|
_timeout = 20;
|
||||||
_clicktype = JAVASCRIPT_CLICK;
|
_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 line(in.takeFirst().trimmed());
|
||||||
QString cmd(line), args;
|
QString cmd(line), args;
|
||||||
int space(line.indexOf(' '));
|
int space(line.indexOf(' '));
|
||||||
@@ -485,22 +505,23 @@ 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()) {
|
||||||
std::shared_ptr<Command> command(it->second->parse
|
command = it->second->parse(this, args, in, filename, linenr);
|
||||||
(this, args, in, linenr));
|
|
||||||
command->line(linenr);
|
|
||||||
return command;
|
|
||||||
} else {
|
} else {
|
||||||
return unknown(line);
|
command = unknown(line);
|
||||||
}
|
}
|
||||||
|
command->file(filename);
|
||||||
|
command->line(linenr);
|
||||||
|
return command;
|
||||||
} catch (Exception& e) {
|
} catch (Exception& e) {
|
||||||
e.line(linenr);
|
e.line(linenr);
|
||||||
|
e.file(filename);
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
void parse(QStringList in) {
|
void parse(QStringList in, QString filename, int line = 1) {
|
||||||
for (int linenr(1), 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(parse(in, linenr));
|
_script.push_back(parseLine(in, filename, line+linenr));
|
||||||
}
|
}
|
||||||
QStringList print() {
|
QStringList print() {
|
||||||
QStringList result;
|
QStringList result;
|
||||||
@@ -628,6 +649,7 @@ class Script: public QObject {
|
|||||||
_testsuites->last()<<testcase;
|
_testsuites->last()<<testcase;
|
||||||
removeSignals(frame);
|
removeSignals(frame);
|
||||||
e.line((*cmd)->line());
|
e.line((*cmd)->line());
|
||||||
|
e.file((*cmd)->file());
|
||||||
if (screenshots)
|
if (screenshots)
|
||||||
try { // write html source and take a last screenshot on error
|
try { // write html source and take a last screenshot on error
|
||||||
{
|
{
|
||||||
@@ -721,7 +743,7 @@ class Script: public QObject {
|
|||||||
_cout.clear();
|
_cout.clear();
|
||||||
_cerr.clear();
|
_cerr.clear();
|
||||||
_ignoreSignalsUntil.clear();
|
_ignoreSignalsUntil.clear();
|
||||||
_functions.clear();
|
_functions.unite(o._functions);
|
||||||
}
|
}
|
||||||
void unset(QString name) {
|
void unset(QString name) {
|
||||||
_rvariables.remove(_variables[name]);
|
_rvariables.remove(_variables[name]);
|
||||||
@@ -824,11 +846,17 @@ class Script: public QObject {
|
|||||||
std::cout<<text<<std::endl<<std::flush;
|
std::cout<<text<<std::endl<<std::flush;
|
||||||
_cout += text + "\n";
|
_cout += text + "\n";
|
||||||
}
|
}
|
||||||
|
void parentlog(QString text) {
|
||||||
|
logging(text);
|
||||||
|
_cout += text + "\n";
|
||||||
|
}
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<Command> unknown(QString line) {
|
std::shared_ptr<Command> unknown(QString command) {
|
||||||
if (!line.size()) return std::shared_ptr<Command>(new Empty());
|
if (!command.size())
|
||||||
if (line[0]=='#') return std::shared_ptr<Command>(new Comment(line));
|
return std::shared_ptr<Command>(new Empty());
|
||||||
throw UnknownCommand(line); // error
|
if (command[0]=='#')
|
||||||
|
return std::shared_ptr<Command>(new Comment(command));
|
||||||
|
throw UnknownCommand(command); // error
|
||||||
}
|
}
|
||||||
void initPrototypes();
|
void initPrototypes();
|
||||||
void add(Command* c) {
|
void add(Command* c) {
|
||||||
@@ -851,9 +879,7 @@ class Script: public QObject {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_ignoreSignalsUntil.clear();
|
_ignoreSignalsUntil.clear();
|
||||||
log(".... signal");
|
log("signal received: loadFinished "+QString(ok?"true":"false"));
|
||||||
log("received loadFinished "+QString(ok?"true":"false"));
|
|
||||||
log(".....................");
|
|
||||||
_signals.push(std::make_pair("loadFinished", QStringList(sig)));
|
_signals.push(std::make_pair("loadFinished", QStringList(sig)));
|
||||||
}
|
}
|
||||||
void loadStarted() {
|
void loadStarted() {
|
||||||
@@ -862,9 +888,7 @@ class Script: public QObject {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_ignoreSignalsUntil.clear();
|
_ignoreSignalsUntil.clear();
|
||||||
log(".... signal");
|
log("signal received: loadStarted");
|
||||||
log("received loadStarted");
|
|
||||||
log(".....................");
|
|
||||||
_signals.push(std::make_pair("loadStarted", QStringList()));
|
_signals.push(std::make_pair("loadStarted", QStringList()));
|
||||||
}
|
}
|
||||||
void frameChanged() {
|
void frameChanged() {
|
||||||
@@ -878,9 +902,7 @@ class Script: public QObject {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_ignoreSignalsUntil.clear();
|
_ignoreSignalsUntil.clear();
|
||||||
log(".... signal");
|
log("signal received: urlChanged "+url.toString());
|
||||||
log("received urlChanged "+url.toString());
|
|
||||||
log(".....................");
|
|
||||||
_signals.push(std::make_pair("urlChanged",
|
_signals.push(std::make_pair("urlChanged",
|
||||||
QStringList(url.toString())));
|
QStringList(url.toString())));
|
||||||
}
|
}
|
||||||
@@ -929,7 +951,7 @@ class Do: public Command {
|
|||||||
return tag()+" "+_selector+_javascript;
|
return tag()+" "+_selector+_javascript;
|
||||||
}
|
}
|
||||||
std::shared_ptr<Command> parse(Script*, QString args,
|
std::shared_ptr<Command> parse(Script*, QString args,
|
||||||
QStringList& in, int) {
|
QStringList& in, QString, 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");
|
||||||
@@ -966,7 +988,8 @@ class Load: public Command {
|
|||||||
QString command() const {
|
QString command() const {
|
||||||
return tag()+" "+_url;
|
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());
|
std::shared_ptr<Load> cmd(new Load());
|
||||||
cmd->_url = args;
|
cmd->_url = args;
|
||||||
return cmd;
|
return cmd;
|
||||||
@@ -1009,7 +1032,8 @@ class Expect: public Command {
|
|||||||
return tag()+" "+_signal._signal
|
return tag()+" "+_signal._signal
|
||||||
+(_signal._args.size()?" "+_signal._args.join(' '):QString());
|
+(_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());
|
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();
|
||||||
@@ -1064,7 +1088,8 @@ class Open: public Command {
|
|||||||
QString command() const {
|
QString command() const {
|
||||||
return tag();
|
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());
|
std::shared_ptr<Open> cmd(new Open());
|
||||||
return cmd;
|
return cmd;
|
||||||
}
|
}
|
||||||
@@ -1091,7 +1116,8 @@ class Sleep: public Command {
|
|||||||
QString command() const {
|
QString command() const {
|
||||||
return tag()+" "+_time;
|
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());
|
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;
|
||||||
@@ -1128,7 +1154,8 @@ class Exit: public Command {
|
|||||||
QString command() const {
|
QString command() const {
|
||||||
return tag();
|
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());
|
std::shared_ptr<Exit> cmd(new Exit());
|
||||||
return cmd;
|
return cmd;
|
||||||
}
|
}
|
||||||
@@ -1155,7 +1182,8 @@ class IgnoreTo: public Command {
|
|||||||
QString command() const {
|
QString command() const {
|
||||||
return tag()+" "+_label;
|
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());
|
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;
|
||||||
@@ -1184,7 +1212,8 @@ class Label: public Command {
|
|||||||
QString command() const {
|
QString command() const {
|
||||||
return tag()+" "+_label;
|
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());
|
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;
|
||||||
@@ -1215,7 +1244,8 @@ class Upload: public Command {
|
|||||||
QString command() const {
|
QString command() const {
|
||||||
return tag()+" "+_selector+" -> "+_filename;
|
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());
|
std::shared_ptr<Upload> cmd(new Upload());
|
||||||
QStringList allargs(args.split("->"));
|
QStringList allargs(args.split("->"));
|
||||||
if (allargs.size()<2)
|
if (allargs.size()<2)
|
||||||
@@ -1263,7 +1293,8 @@ class Exists: public Command {
|
|||||||
QString command() const {
|
QString command() const {
|
||||||
return tag()+" "+_selector+(_text.size()?" -> "+_text:QString());
|
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());
|
std::shared_ptr<Exists> cmd(new Exists());
|
||||||
QStringList allargs(args.split("->"));
|
QStringList allargs(args.split("->"));
|
||||||
if (allargs.size()<2) {
|
if (allargs.size()<2) {
|
||||||
@@ -1315,7 +1346,8 @@ class Not: public Command {
|
|||||||
QString command() const {
|
QString command() const {
|
||||||
return tag()+" "+_selector+(_text.size()?" -> "+_text:QString());
|
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());
|
std::shared_ptr<Not> cmd(new Not());
|
||||||
QStringList allargs(args.split("->"));
|
QStringList allargs(args.split("->"));
|
||||||
if (allargs.size()<2) {
|
if (allargs.size()<2) {
|
||||||
@@ -1366,7 +1398,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, int) {
|
QStringList& in, QString, 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();
|
||||||
@@ -1429,10 +1461,10 @@ 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, int line) {
|
QStringList& in, QString file, int line) {
|
||||||
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->parse(in, line+1);
|
cmd->_next = script->parseLine(in, file, line+1);
|
||||||
cmd->_next->log(false); // suppress logging of subcommand
|
cmd->_next->log(false); // suppress logging of subcommand
|
||||||
return cmd;
|
return cmd;
|
||||||
}
|
}
|
||||||
@@ -1508,7 +1540,8 @@ class Click: public Command {
|
|||||||
:*_clicktype==Script::JAVASCRIPT_CLICK?" javascript":"")
|
:*_clicktype==Script::JAVASCRIPT_CLICK?" javascript":"")
|
||||||
:"")+" "+_selector;
|
:"")+" "+_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());
|
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;
|
||||||
@@ -1569,14 +1602,14 @@ 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, int line) {
|
QStringList& in, QString file, int line) {
|
||||||
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->parse(in, line+1);
|
cmd->_next = script->parseLine(in, file, line+1);
|
||||||
cmd->_next->log(false); // suppress logging of subcommand
|
cmd->_next->log(false); // suppress logging of subcommand
|
||||||
}
|
}
|
||||||
return cmd;
|
return cmd;
|
||||||
@@ -1614,7 +1647,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&, int) {
|
QStringList&, QString, 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;
|
||||||
@@ -1643,7 +1676,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&, int) {
|
QStringList&, QString, 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;
|
||||||
@@ -1676,7 +1709,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&, int) {
|
QStringList&, QString, 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;
|
||||||
@@ -1715,7 +1748,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&, int) {
|
QStringList&, QString, 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");
|
||||||
@@ -1779,7 +1812,7 @@ class ClickType: public Command {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
std::shared_ptr<Command> parse(Script* script, QString args,
|
std::shared_ptr<Command> parse(Script* script, QString args,
|
||||||
QStringList&, int) {
|
QStringList&, QString, 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")
|
||||||
@@ -1823,7 +1856,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&, int) {
|
QStringList&, QString, 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)
|
||||||
@@ -1887,15 +1920,15 @@ 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, int) {
|
QStringList& in, QString file, int line) {
|
||||||
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(" "));
|
QStringList allargs(args.split(" ", QString::SkipEmptyParts));
|
||||||
cmd->_name = allargs.takeFirst().trimmed();
|
cmd->_name = allargs.takeFirst().trimmed();
|
||||||
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));
|
cmd->_script->parse(subCommandBlock(in), file, line+1);
|
||||||
return cmd;
|
return cmd;
|
||||||
}
|
}
|
||||||
bool execute(Script* script, QWebFrame*) {
|
bool execute(Script* script, QWebFrame*) {
|
||||||
@@ -1935,10 +1968,10 @@ 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&, int) {
|
QStringList&, QString, 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(" "));
|
QStringList allargs(args.split(" ", QString::SkipEmptyParts));
|
||||||
cmd->_name = allargs.takeFirst().trimmed();
|
cmd->_name = allargs.takeFirst().trimmed();
|
||||||
cmd->_args = commaSeparatedList(allargs.join(' '));
|
cmd->_args = commaSeparatedList(allargs.join(' '));
|
||||||
return cmd;
|
return cmd;
|
||||||
@@ -1980,7 +2013,7 @@ 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, int) {
|
QStringList& in, QString file, int line) {
|
||||||
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);
|
||||||
@@ -1988,11 +2021,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));
|
cmd->_script->parse(subCommandBlock(in), file, line+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));
|
cmd->_else->parse(subCommandBlock(in), file, line+1);
|
||||||
}
|
}
|
||||||
return cmd;
|
return cmd;
|
||||||
}
|
}
|
||||||
@@ -2041,7 +2074,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&, int) {
|
QStringList&, QString, 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;
|
||||||
@@ -2070,7 +2103,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&, int) {
|
QStringList&, QString, 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;
|
||||||
@@ -2108,7 +2141,7 @@ 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, int line) {
|
QStringList& in, QString file, int line) {
|
||||||
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("[=^~<>]")));
|
||||||
@@ -2117,7 +2150,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->parse(in, line+1);
|
cmd->_next = script->parseLine(in, file, line+1);
|
||||||
cmd->_next->log(false); // suppress logging of subcommand
|
cmd->_next->log(false); // suppress logging of subcommand
|
||||||
}
|
}
|
||||||
return cmd;
|
return cmd;
|
||||||
@@ -2165,7 +2198,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&, int) {
|
QStringList&, QString, int) {
|
||||||
std::shared_ptr<> cmd(new ());
|
std::shared_ptr<> cmd(new ());
|
||||||
return cmd;
|
return cmd;
|
||||||
}
|
}
|
||||||
@@ -2189,20 +2222,29 @@ 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()) {
|
if (_command->log()) {
|
||||||
_script->log("---- line: "+QString::number(_command->line()));
|
_script->log(QString
|
||||||
_script->log(_command->command());
|
("%1:%2 \\ %3")
|
||||||
|
.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);
|
_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("---------------------");
|
_script->log(QString
|
||||||
|
("%1:%2 / %3")
|
||||||
|
.arg(_command->file()).arg(_command->line())
|
||||||
|
.arg(_command->command()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool Command::runScript(Command* parentCommand,
|
inline bool Command::runScript(Command* parentCommand,
|
||||||
@@ -2210,26 +2252,27 @@ inline bool Command::runScript(Command* parentCommand,
|
|||||||
Script* parent, QWebFrame* frame,
|
Script* parent, QWebFrame* frame,
|
||||||
QStringList vars,
|
QStringList vars,
|
||||||
QStringList args) {
|
QStringList args) {
|
||||||
script->set(*parent);
|
Script scriptCopy(*script); // only work with a copy of script
|
||||||
|
scriptCopy.set(*parent);
|
||||||
if (args.size()!=vars.size())
|
if (args.size()!=vars.size())
|
||||||
throw WrongNumberOfArguments(vars, args);
|
throw WrongNumberOfArguments(vars, args);
|
||||||
for (QStringList::iterator var(vars.begin()), arg(args.begin());
|
for (QStringList::iterator var(vars.begin()), arg(args.begin());
|
||||||
var<vars.end() && arg<args.end(); ++var, ++arg)
|
var<vars.end() && arg<args.end(); ++var, ++arg)
|
||||||
script->set(*var, parent->replacevars(*arg));
|
scriptCopy.set(*var, parent->replacevars(*arg));
|
||||||
try {
|
try {
|
||||||
connect(script.get(), SIGNAL(logging(QString)),
|
connect(&scriptCopy, SIGNAL(logging(QString)),
|
||||||
parent, SLOT(log(QString)));
|
parent, SLOT(parentlog(QString)));
|
||||||
parent->removeSignals(frame);
|
parent->removeSignals(frame);
|
||||||
bool res(script->run(frame));
|
bool res(scriptCopy.run(frame));
|
||||||
parent->addSignals(frame);
|
parent->addSignals(frame);
|
||||||
disconnect(script.get(), SIGNAL(logging(QString)),
|
disconnect(&scriptCopy, SIGNAL(logging(QString)),
|
||||||
parent, SLOT(log(QString)));
|
parent, SLOT(parentlog(QString)));
|
||||||
parentCommand->_result = script->result();
|
parentCommand->_result = scriptCopy.result();
|
||||||
return res;
|
return res;
|
||||||
} catch (const std::exception& x) {
|
} catch (const std::exception& x) {
|
||||||
parent->addSignals(frame);
|
parent->addSignals(frame);
|
||||||
disconnect(script.get(), SIGNAL(logging(QString)),
|
disconnect(&scriptCopy, SIGNAL(logging(QString)),
|
||||||
parent, SLOT(log(QString)));
|
parent, SLOT(parentlog(QString)));
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -19,7 +19,10 @@ class Exception: public std::exception {
|
|||||||
return _what.toStdString().c_str();
|
return _what.toStdString().c_str();
|
||||||
}
|
}
|
||||||
void line(int linenr) {
|
void line(int linenr) {
|
||||||
if (linenr>0) _what="line "+QString::number(linenr)+": "+_what;
|
if (linenr>0) _what=QString::number(linenr)+" "+_what;
|
||||||
|
}
|
||||||
|
void file(QString filename) {
|
||||||
|
if (filename.size()) _what=filename+":"+_what;
|
||||||
}
|
}
|
||||||
protected:
|
protected:
|
||||||
QString _what;
|
QString _what;
|
||||||
@@ -241,8 +244,7 @@ class FunctionCallFailed: public TestFailed {
|
|||||||
|
|
||||||
class FunctionNotFound: public TestFailed {
|
class FunctionNotFound: public TestFailed {
|
||||||
public:
|
public:
|
||||||
FunctionNotFound(QString name):
|
FunctionNotFound(QString name): TestFailed("function not found: "+name) {
|
||||||
TestFailed("function not found: "+name) {
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -122,13 +122,13 @@ class TestGUI: public QMainWindow, protected Ui::TestGUI {
|
|||||||
std::shared_ptr<xml::Node> testsuites(new xml::Node("testsuite"));
|
std::shared_ptr<xml::Node> testsuites(new xml::Node("testsuite"));
|
||||||
if (_setupscriptactive->isEnabled()
|
if (_setupscriptactive->isEnabled()
|
||||||
&& _setupscriptactive->isChecked()) {
|
&& _setupscriptactive->isChecked()) {
|
||||||
script.parse(_setupscript->toPlainText().split('\n'));
|
script.parse(_setupscript->toPlainText().split('\n'), "setup");
|
||||||
script.run(_web->page()->mainFrame(), testsuites, QString(), false);
|
script.run(_web->page()->mainFrame(), testsuites, QString(), false);
|
||||||
script.reset();
|
script.reset();
|
||||||
}
|
}
|
||||||
QString text(_testscript->textCursor().selection().toPlainText());
|
QString text(_testscript->textCursor().selection().toPlainText());
|
||||||
if (text.isEmpty()) text = _testscript->toPlainText();
|
if (text.isEmpty()) text = _testscript->toPlainText();
|
||||||
script.parse(text.split('\n'));
|
script.parse(text.split('\n'), "script");
|
||||||
script.run(_web->page()->mainFrame(), testsuites, QString(), false);
|
script.run(_web->page()->mainFrame(), testsuites, QString(), false);
|
||||||
} catch (std::exception &x) {
|
} catch (std::exception &x) {
|
||||||
QMessageBox::critical(this, tr("Script Failed"),
|
QMessageBox::critical(this, tr("Script Failed"),
|
||||||
@@ -222,10 +222,10 @@ class TestGUI: public QMainWindow, protected Ui::TestGUI {
|
|||||||
std::shared_ptr<xml::Node> testsuites(new xml::Node("testsuite"));
|
std::shared_ptr<xml::Node> testsuites(new xml::Node("testsuite"));
|
||||||
Script script;
|
Script script;
|
||||||
TestWebPage page(0, true);
|
TestWebPage page(0, true);
|
||||||
script.parse(_setupscript->toPlainText().split('\n'));
|
script.parse(_setupscript->toPlainText().split('\n'), "setup");
|
||||||
script.run(page.mainFrame(), testsuites, QString(), false);
|
script.run(page.mainFrame(), testsuites, QString(), false);
|
||||||
_setupScript.cleanup();
|
_setupScript.cleanup();
|
||||||
_setupScript.parse(_setupscript->toPlainText().split('\n'));
|
_setupScript.parse(_setupscript->toPlainText().split('\n'), "setup");
|
||||||
_setupScript.run(page.mainFrame(), testsuites, QString(), false);;
|
_setupScript.run(page.mainFrame(), testsuites, QString(), false);;
|
||||||
_setupscriptstatus->setText(trUtf8("✔"));
|
_setupscriptstatus->setText(trUtf8("✔"));
|
||||||
_setupscriptactive->setEnabled(true);
|
_setupscriptactive->setEnabled(true);
|
||||||
|
@@ -160,7 +160,7 @@ int main(int argc, char *argv[]) try {
|
|||||||
QString txt(QString::fromUtf8(f.readAll()));
|
QString txt(QString::fromUtf8(f.readAll()));
|
||||||
testcase.attr("name") = "parse test suite file";
|
testcase.attr("name") = "parse test suite file";
|
||||||
testsuite<<testcase;
|
testsuite<<testcase;
|
||||||
script.parse(txt.split('\n'));
|
script.parse(txt.split('\n'), file);
|
||||||
expectedtestcases = script.steps()+2;
|
expectedtestcases = script.steps()+2;
|
||||||
if (failed) {
|
if (failed) {
|
||||||
script.log("FAILED: "+file+" skipped due to previous error");
|
script.log("FAILED: "+file+" skipped due to previous error");
|
||||||
|
Reference in New Issue
Block a user