diff --git a/src/commands.hxx b/src/commands.hxx index e092852..8337143 100644 --- a/src/commands.hxx +++ b/src/commands.hxx @@ -81,19 +81,20 @@ class Logger { ~Logger(); private: Command* _command; + Command* _previous; Script* _script; }; class Command: public QObject { Q_OBJECT; public: - Command(): _log(true), _line(-1) {} + Command(): _log(true), _line(-1), _indent(0) {} virtual ~Command() {} virtual QString tag() const = 0; virtual QString description() const = 0; virtual QString command() const = 0; virtual std::shared_ptr parse(Script*, QString, - QStringList&, QString, int) = 0; + QStringList&, QString, int, int) = 0; virtual bool execute(Script*, QWebFrame*) = 0; void line(int linenr) { _line = linenr; @@ -107,6 +108,12 @@ class Command: public QObject { QString file() const { return _file; } + void indent(int i) { + _indent = i; + } + int indent() const { + return _indent; + } bool log() { return _log; } @@ -219,6 +226,7 @@ class Command: public QObject { private: int _line; QString _file; + int _indent; }; class Empty: public Command { @@ -236,7 +244,7 @@ class Empty: public Command { return tag(); } std::shared_ptr parse(Script*, QString, - QStringList&, QString, int) { + QStringList&, QString, int, int) { std::shared_ptr cmd(new Empty()); return cmd; } @@ -261,7 +269,7 @@ class Comment: public Command { return _comment; } std::shared_ptr parse(Script*, QString args, - QStringList&, QString, int) { + QStringList&, QString, int, int) { std::shared_ptr cmd(new Comment(args)); return cmd; } @@ -333,7 +341,7 @@ class Screenshot: public Command { return tag()+" "+_filename; } std::shared_ptr parse(Script*, QString args, - QStringList&, QString, int) { + QStringList&, QString, int, int) { std::shared_ptr cmd(new Screenshot()); cmd->_filename = args; return cmd; @@ -411,12 +419,6 @@ 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("\"", """); @@ -434,9 +436,16 @@ class Script: public QObject { .replace(" ", " ").replace("&", "&"); } public: - Script(): _clicktype(JAVASCRIPT_CLICK) { + Script(): _clicktype(JAVASCRIPT_CLICK), _command(0) { initPrototypes(); } + Script(const Script& o): + QObject(), + _prototypes(o._prototypes), + _script(o._script), + _command(0) { + set(o); + } QString syntax() const { return "Script syntax is a text file that consists of list of commands. Each " @@ -494,7 +503,8 @@ class Script: public QObject { _clicktype = JAVASCRIPT_CLICK; } std::shared_ptr parseLine(QStringList& in, - QString filename, int linenr) try { + QString filename, int linenr, + int indent) try { std::shared_ptr command; QString line(in.takeFirst().trimmed()); QString cmd(line), args; @@ -505,23 +515,24 @@ class Script: public QObject { } Prototypes::const_iterator it(_prototypes.find(cmd)); if (it!=_prototypes.end()) { - command = it->second->parse(this, args, in, filename, linenr); + command = it->second->parse(this, args, in, filename, linenr, indent); } else { command = unknown(line); } command->file(filename); command->line(linenr); + command->indent(indent); return command; } catch (Exception& e) { e.line(linenr); e.file(filename); 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); oldsize=in.size(), 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 result; @@ -673,6 +684,12 @@ class Script: public QObject { if (!_signals.empty()) throw UnhandledSignals(_signals); return res; } + Command* command() { + return _command; + } + void command(Command* cmd) { + _command = cmd; + } QString& cout() { return _cout; } @@ -835,8 +852,16 @@ class Script: public QObject { disconnect(&_timer, SIGNAL(timeout()), this, SLOT(timeout())); } public Q_SLOTS: - void log(QString text) { - text = QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss ")+text; + void log(QString text, Command* command = 0) { + 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); std::cout< _testsuites; ///< only valid within run QString _testclass; + Command* _command; }; class Do: public Command { @@ -948,10 +974,10 @@ class Do: public Command { "one space"; } QString command() const { - return tag()+" "+_selector+_javascript; + return tag()+" "+_selector+(_javascript.size()?"\n"+_javascript:""); } std::shared_ptr parse(Script*, QString args, - QStringList& in, QString, int) { + QStringList& in, QString, int, int) { std::shared_ptr cmd(new Do()); cmd->_selector = args.trimmed(); cmd->_javascript = subCommandBlock(in).join("\n"); @@ -961,12 +987,13 @@ class Do: public Command { Logger log(this, script); QWebElement element(frame->documentElement()); if (_selector.size()) { - QWebElement element(find(frame, script->replacevars(_selector))); + element = find(frame, script->replacevars(_selector)); if (element.isNull()) throw ElementNotFound(script->replacevars(_selector)); } _result = element.evaluateJavaScript(script->replacevars(_javascript)).toString(); + log("result: "+(_result.size()?_result:"(void)")); return true; } private: @@ -989,7 +1016,7 @@ class Load: public Command { return tag()+" "+_url; } std::shared_ptr parse(Script*, QString args, - QStringList&, QString, int) { + QStringList&, QString, int, int) { std::shared_ptr cmd(new Load()); cmd->_url = args; return cmd; @@ -1033,7 +1060,7 @@ class Expect: public Command { +(_signal._args.size()?" "+_signal._args.join(' '):QString()); } std::shared_ptr parse(Script*, QString args, - QStringList&, QString, int) { + QStringList&, QString, int, int) { std::shared_ptr cmd(new Expect()); cmd->_signal._args = args.split(" "); cmd->_signal._signal = cmd->_signal._args.takeFirst(); @@ -1089,7 +1116,7 @@ class Open: public Command { return tag(); } std::shared_ptr parse(Script*, QString, - QStringList&, QString, int) { + QStringList&, QString, int, int) { std::shared_ptr cmd(new Open()); return cmd; } @@ -1117,7 +1144,7 @@ class Sleep: public Command { return tag()+" "+_time; } std::shared_ptr parse(Script*, QString time, - QStringList&, QString, int) { + QStringList&, QString, int, int) { std::shared_ptr cmd(new Sleep()); cmd->_time = "10"; // default: 10s if (time.size()) cmd->_time = time; @@ -1155,7 +1182,7 @@ class Exit: public Command { return tag(); } std::shared_ptr parse(Script*, QString, - QStringList&, QString, int) { + QStringList&, QString, int, int) { std::shared_ptr cmd(new Exit()); return cmd; } @@ -1183,7 +1210,7 @@ class IgnoreTo: public Command { return tag()+" "+_label; } std::shared_ptr parse(Script*, QString args, - QStringList&, QString, int) { + QStringList&, QString, int, int) { std::shared_ptr cmd(new IgnoreTo()); if (!args.size()) throw BadArgument("ignoreto needs a label"); cmd->_label=args; @@ -1213,7 +1240,7 @@ class Label: public Command { return tag()+" "+_label; } std::shared_ptr parse(Script*, QString args, - QStringList&, QString, int) { + QStringList&, QString, int, int) { std::shared_ptr