more improve expect load; better logging in case of exception

master
Marc Wäckerlin 7 years ago
parent 006a5a2e6e
commit 35f5aa9676
  1. 237
      src/commands.hxx

@ -98,6 +98,10 @@ class Command: public QObject {
virtual std::shared_ptr<Command> parse(Script*, QString,
QStringList&, QString, int, int) = 0;
virtual bool execute(Script*, QWebFrame*) = 0;
static void error(Logger& log, const Exception& e) {
log(QString(" FAILED: ")+e.what());
throw e;
}
void line(int linenr) {
_line = linenr;
}
@ -128,9 +132,9 @@ class Command: public QObject {
virtual bool isTestcase() {
return true;
}
static void realMouseClick(QWebFrame* frame, QString selector) {
static void realMouseClick(Logger& log, QWebFrame* frame, QString selector) {
QWebElement element(find(frame, selector));
if (element.isNull()) throw ElementNotFound(selector);
if (element.isNull()) error(log, ElementNotFound(selector));
realMouseClick(element);
}
static void realMouseClick(const QWebElement& element) {
@ -168,7 +172,7 @@ class Command: public QObject {
QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
}
protected:
bool runScript(Command* parentCommand,
bool runScript(Logger& log, Command* parentCommand,
std::shared_ptr<Script> script,
Script* parent, QWebFrame* frame,
QStringList vars = QStringList(),
@ -299,10 +303,10 @@ class Comment: public Command {
class Screenshot: public Command {
public:
static QString sourceHtml(int line, QString target, QString base,
static QString sourceHtml(Logger& log, int line, QString target, QString base,
QString name, QWebFrame* frame) {
if (!QDir(target).exists() && !QDir().mkpath(target))
throw DirectoryCannotBeCreated(target);
error(log, DirectoryCannotBeCreated(target));
QCoreApplication::processEvents();
QString filename(target+QDir::separator()+
QString("%4-%1-%2-%3.html")
@ -313,13 +317,13 @@ class Screenshot: public Command {
.toString("yyyyMMddHHmmss")));
QFile file(filename);
if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
throw CannotWriteSouceHTML(filename);
error(log, CannotWriteSouceHTML(filename));
QTextStream out(&file);
out<<frame->toHtml();
if (out.status()!=QTextStream::Ok) throw CannotWriteSouceHTML(filename);
if (out.status()!=QTextStream::Ok) error(log, CannotWriteSouceHTML(filename));
return QDir(filename).absolutePath();
}
static QString screenshot(int line, QString target, QString base,
static QString screenshot(Logger& log, int line, QString target, QString base,
QString name, QWebFrame* frame) {
bool wasShown(frame->page()->view()->isVisible());
frame->page()->view()->show();
@ -330,7 +334,7 @@ class Screenshot: public Command {
painter.end();
if (!wasShown) frame->page()->view()->hide();
if (!QDir(target).exists() && !QDir().mkpath(target))
throw DirectoryCannotBeCreated(target);
error(log, DirectoryCannotBeCreated(target));
QCoreApplication::processEvents();
QString filename(target+QDir::separator()+
QString("%4-%1-%2-%3.png")
@ -339,7 +343,7 @@ class Screenshot: public Command {
.arg(name)
.arg(QDateTime::currentDateTime()
.toString("yyyyMMddHHmmss")));
if (!image.save(filename)) throw CannotWriteScreenshot(filename);
if (!image.save(filename)) error(log, CannotWriteScreenshot(filename));
return QDir(filename).absolutePath();
}
QString tag() const {
@ -639,8 +643,9 @@ class Script: public QObject {
// timeout may happen during load due to bad internet connection
if (screenshots)
try { // take a screenshot on error
Logger log(0, this);
QString filename(Screenshot::screenshot
((*cmd)->line(), targetdir(),
(log, (*cmd)->line(), targetdir(),
_testclass,
QString("retry-%1")
.arg((ulong)retries, 2, 10,
@ -717,14 +722,16 @@ class Script: public QObject {
if (screenshots)
try { // write html source and take a last screenshot on error
{
Logger log(0, this);
QString filename(Screenshot::sourceHtml
((*cmd)->line(), targetdir(),
(log, (*cmd)->line(), targetdir(),
_testclass,
"error", frame));
plainlog("[[ATTACHMENT|"+filename+"]]");
} {
Logger log(0, this);
QString filename(Screenshot::screenshot
((*cmd)->line(), targetdir(),
(log, (*cmd)->line(), targetdir(),
_testclass,
"error", frame));
plainlog("[[ATTACHMENT|"+filename+"]]");
@ -734,7 +741,7 @@ class Script: public QObject {
}
}
removeSignals(frame);
if (!_signals.empty()) throw UnhandledSignals(_signals);
if (!_signals.empty()) error(UnhandledSignals(_signals));
progress("success", 0, 0);
return res;
}
@ -798,9 +805,9 @@ class Script: public QObject {
QStringList variables() {
return _variables.keys();
}
QString variable(QString name) {
QString variable(Logger& log, QString name) {
QMap<QString, QString>::iterator it(_variables.find(name));
if (it==_variables.end()) throw VariableNotFound(name);
if (it==_variables.end()) error(VariableNotFound(name));
return *it;
}
/// Copy context from other script
@ -829,10 +836,10 @@ class Script: public QObject {
void function(QString name, std::shared_ptr<Function> f) {
_functions[name] = f;
}
std::shared_ptr<Function> function(QString name) {
std::shared_ptr<Function> function(Logger& log, QString name) {
QMap<QString, std::shared_ptr<Function> >::iterator
it(_functions.find(name));
if (it==_functions.end()) throw FunctionNotFound(name);
if (it==_functions.end()) error(FunctionNotFound(name));
return *it;
}
void timeout(int t) {
@ -942,6 +949,10 @@ class Script: public QObject {
_cout += text + "\n";
}
private:
void error(const Exception& e) {
log(QString(" FAILED: ")+e.what());
throw e;
}
std::shared_ptr<Command> unknown(QString command) {
if (!command.size())
return std::shared_ptr<Command>(new Empty());
@ -998,7 +1009,7 @@ class Script: public QObject {
QStringList(url.toString())));
}
void timeout() {
throw TimeOut();
error(TimeOut());
}
private:
typedef std::map<QString, std::shared_ptr<Command>> Prototypes;
@ -1056,7 +1067,7 @@ class Do: public Command {
if (_selector.size()) {
element = find(frame, script->replacevars(_selector));
if (element.isNull())
throw ElementNotFound(script->replacevars(_selector));
error(log, ElementNotFound(script->replacevars(_selector)));
}
_result =
element.evaluateJavaScript(script->replacevars(_javascript)).toString();
@ -1138,19 +1149,19 @@ class Expect: public Command {
QStringList args(script->replacevars(_signal._args));
Script::Signal lastsignal(script->getSignal());
if (_signal._signal=="load") { // special signal load
if (lastsignal.first=="loadStarted") {
log("ignore loadStarted");
while (lastsignal.first=="loadStarted") {
log("ignore signal: loadStarted");
lastsignal = script->getSignal(); // ignore optional loadStarted
}
if (lastsignal.first!="urlChanged" || (args.size() && lastsignal.second!=args))
throw WrongSignal("urlChanged", args, lastsignal);
error(log, WrongSignal("urlChanged", args, lastsignal));
lastsignal = script->getSignal();
args=QStringList("true");
if (lastsignal.first!="loadFinished" || (lastsignal.second!=args))
throw WrongSignal("loadFinished", args, lastsignal);
error(log, WrongSignal("loadFinished", args, lastsignal));
} else {
if (lastsignal.first!=_signal._signal || (args.size() && lastsignal.second!=args))
throw WrongSignal(_signal._signal, args, lastsignal);
error(log, WrongSignal(_signal._signal, args, lastsignal));
}
return true;
}
@ -1221,8 +1232,8 @@ class Sleep: public Command {
bool ok;
unsigned int time(script->replacevars(_time).toUInt(&ok));
if (!ok)
throw BadArgument(script->replacevars(_time)
+" should be a number of seconds");
error(log, BadArgument(script->replacevars(_time)
+" should be a number of seconds"));
sleep(time);
return true;
}
@ -1342,7 +1353,7 @@ class Upload: public Command {
QStringList allargs(args.split("->"));
if (allargs.size()<2)
throw BadArgument(tag()+"requires <selector> -> <filename>, "
"instead of: \""+args+"\"");
"instead of: \""+args+"\"");
cmd->_selector = allargs.takeFirst().trimmed();
cmd->_filename = allargs.join("->").trimmed();
return cmd;
@ -1364,9 +1375,9 @@ class Upload: public Command {
if (files.size()==1) filename=files[0];
}
page->setNextUploadFile(filename);
realMouseClick(frame, script->replacevars(_selector));
realMouseClick(log, frame, script->replacevars(_selector));
if (page->uploadPrepared())
throw SetFileUploadFailed(script->replacevars(_selector), filename);
error(log, SetFileUploadFailed(script->replacevars(_selector), filename));
return true;
}
private:
@ -1416,14 +1427,14 @@ class Exists: public Command {
}
QWebElement element(find(frame, selector));
if (text.isEmpty())
throw AssertionFailed("element not found: "+selector);
error(log, AssertionFailed("element not found: "+selector));
else if (element.isNull())
throw AssertionFailed("expected \""+text+"\" in non existing element "
+selector);
error(log, AssertionFailed("expected \""+text+"\" in non existing element "
+selector));
else
throw AssertionFailed("not found \""+text+"\" in \""
+notfound.join("\", \"")+"\" on "+selector);
return true; // never reached due to throw above
error(log, AssertionFailed("not found \""+text+"\" in \""
+notfound.join("\", \"")+"\" on "+selector));
return true; // never reached due to error, above
}
private:
QString _selector;
@ -1465,10 +1476,10 @@ class Not: public Command {
QString text(script->replacevars(_text));
Q_FOREACH(QWebElement element, frame->findAllElements(selector)) {
if (text.isEmpty())
throw AssertionFailed("element must not exists: "+selector);
error(log, AssertionFailed("element must not exists: "+selector));
if (element.toOuterXml().indexOf(text)!=-1)
throw AssertionFailed("\""+text+"\" must not be in \""
+element.toInnerXml()+"\" on "+selector);
error(log, AssertionFailed("\""+text+"\" must not be in \""
+element.toInnerXml()+"\" on "+selector));
}
return true;
}
@ -1517,23 +1528,23 @@ class Execute: public Command {
exec.setProcessChannelMode(QProcess::MergedChannels);
exec.start(command, args);
if (!exec.waitForStarted())
throw CannotStartScript(command, args, scripttxt);
error(log, CannotStartScript(command, args, scripttxt));
if (scripttxt.size()) {
if (exec.write(scripttxt.toUtf8())!=scripttxt.toUtf8().size() ||
!exec.waitForBytesWritten(60000))
throw CannotLoadScript(command, args, scripttxt);
error(log, CannotLoadScript(command, args, scripttxt));
}
exec.closeWriteChannel();
if (!exec.waitForFinished(60000) && exec.state()!=QProcess::NotRunning)
throw ScriptNotFinished(command, args, scripttxt);
error(log, ScriptNotFinished(command, args, scripttxt));
QString stdout(exec.readAllStandardOutput());
QString stderr(exec.readAllStandardError());
_result = stdout;
log("result: "+(_result.size()?_result:"(void)"));
script->log(stdout);
if (exec.exitCode()!=0 || exec.exitStatus()!=QProcess::NormalExit)
throw ScriptExecutionFailed(command, args, scripttxt,
exec.exitCode(), stdout, stderr);
error(log, ScriptExecutionFailed(command, args, scripttxt,
exec.exitCode(), stdout, stderr));
return true;
}
private:
@ -1585,8 +1596,8 @@ class Download: public Command {
QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
log("download terminated "+
QString(_netsuccess&&_filesuccess?"successfully":"with error"));
if (!_netsuccess) throw DownloadFailed(_realfilename);
if (!_filesuccess) throw WriteFileFailed(_realfilename);
if (!_netsuccess) error(log, DownloadFailed(_realfilename));
if (!_filesuccess) error(log, WriteFileFailed(_realfilename));
log["[[ATTACHMENT|"+QDir(_realfilename).absolutePath()+"]]"];
disconnect(frame->page(), SIGNAL(unsupportedContent(QNetworkReply*)),
this, SLOT(unsupportedContent(QNetworkReply*)));
@ -1660,14 +1671,14 @@ class Click: public Command {
QString clicktarget(script->replacevars(_selector));
switch (_clicktype ? *_clicktype : script->clicktype()) {
case Script::REAL_MOUSE_CLICK: {
realMouseClick(frame, clicktarget);
realMouseClick(log, frame, clicktarget);
break;
}
case Script::JAVASCRIPT_CLICK:
default: {
QWebElement element(find(frame, clicktarget));
if (element.isNull())
throw ElementNotFound(clicktarget);
error(log, ElementNotFound(clicktarget));
_result = element.evaluateJavaScript("this.click();").toString();
if (_result.size()) log("result: "+_result.size());
break;
@ -1791,8 +1802,8 @@ class Timeout: public Command {
Logger log(this, script);
bool ok;
int timeout(script->replacevars(_timeout).toInt(&ok));
if (!ok) throw BadArgument(script->replacevars(_timeout)
+" should be a number of seconds");
if (!ok) error(log, BadArgument(script->replacevars(_timeout)
+" should be a number of seconds"));
script->timeout(timeout);
return true;
}
@ -1826,9 +1837,9 @@ class CaCertificate: public Command {
QFile cacertfile(script->path()+filename);
if (!cacertfile.exists()) cacertfile.setFileName(filename); // try without path
if (!cacertfile.exists() || !cacertfile.open(QIODevice::ReadOnly))
throw FileNotFound(filename);
error(log, FileNotFound(filename));
QSslCertificate cacert(&cacertfile);
if (cacert.isNull()) throw NotACertificate(filename);
if (cacert.isNull()) error(log, NotACertificate(filename));
QSslSocket::addDefaultCaCertificate(cacert);
return true;
}
@ -1873,19 +1884,19 @@ class ClientCertificate: public Command {
QFile certfile(script->path()+filename);
if (!certfile.exists()) certfile.setFileName(filename);
if (!certfile.exists() || !certfile.open(QIODevice::ReadOnly))
throw FileNotFound(filename);
error(log, FileNotFound(filename));
QSslCertificate cert(&certfile);
if (cert.isNull()) throw NotACertificate(filename);
if (cert.isNull()) error(log, NotACertificate(filename));
sslConfig.setLocalCertificate(cert);
filename = script->replacevars(_keyfile);
QFile keyfile(script->path()+filename);
if (!keyfile.exists()) keyfile.setFileName(filename);
if (!keyfile.exists() || !keyfile.open(QIODevice::ReadOnly))
throw FileNotFound(filename);
error(log, FileNotFound(filename));
keyfile.open(QIODevice::ReadOnly);
QSslKey k(&keyfile, QSsl::Rsa, QSsl::Pem,
QSsl::PrivateKey, script->replacevars(_password).toUtf8());
if (k.isNull()) throw KeyNotReadable(filename);
if (k.isNull()) error(log, KeyNotReadable(filename));
sslConfig.setPrivateKey(k);
QSslConfiguration::setDefaultConfiguration(sslConfig);
return true;
@ -1970,7 +1981,7 @@ class SetValue: public Command {
QStringList allargs(args.split("->"));
if (allargs.size()<2)
throw BadArgument(tag()+" requires <selector> -> <value>, "
"instead of: \""+args+"\"");
"instead of: \""+args+"\"");
cmd->_selector = allargs.takeFirst().trimmed();
cmd->_value = allargs.join("->").trimmed();
return cmd;
@ -1979,7 +1990,7 @@ class SetValue: public Command {
Logger log(this, script);
QWebElement element(find(frame, script->replacevars(_selector)));
if (element.isNull())
throw ElementNotFound(script->replacevars(_selector));
error(log, ElementNotFound(script->replacevars(_selector)));
QString value(script->replacevars(_value));
if (element.tagName()=="SELECT") {
// value is a comma seperated list of option values
@ -2045,12 +2056,12 @@ class Function: public Command {
Logger log(this, script, false);
return true;
}
bool call(Command* parentCommand, QStringList args,
Script* script, QWebFrame* frame) {
bool call(Logger& log, Command* parentCommand, QStringList args,
Script* script, QWebFrame* frame) {
try {
return runScript(parentCommand, _script, script, frame, _vars, args);
} catch (const std::exception& x) {
throw FunctionCallFailed(_name, _vars, args, x);
return runScript(log, parentCommand, _script, script, frame, _vars, args);
} catch (const Exception& x) {
error(log, FunctionCallFailed(_name, _vars, args, x));
}
}
private:
@ -2087,8 +2098,8 @@ class Call: public Command {
}
bool execute(Script* script, QWebFrame* frame) {
Logger log(this, script);
return script->function(_name)->call(this, script->replacevars(_args),
script, frame);
return script->function(log, _name)->call(log, this, script->replacevars(_args),
script, frame);
}
public:
QString _name;
@ -2178,28 +2189,28 @@ class If: public Command {
+selector+" "+_cmp+" "+value);
} else {
switch (_cmp[0].toLatin1()) {
case '=': check = script->variable(_variable)==value;
case '=': check = script->variable(log, _variable)==value;
break;
case '!': check = script->variable(_variable)!=value;
case '!': check = script->variable(log, _variable)!=value;
break;
case '.': check = script->variable(_variable).contains(value);
case '.': check = script->variable(log, _variable).contains(value);
break;
case '^': check = !script->variable(_variable).contains(value);
case '^': check = !script->variable(log, _variable).contains(value);
break;
case '~': check =
script->variable(_variable).contains(QRegularExpression(value));
script->variable(log, _variable).contains(QRegularExpression(value));
break;
case '<': check = script->variable(_variable).toInt()<value.toInt();
case '<': check = script->variable(log, _variable).toInt()<value.toInt();
break;
case '>': check = script->variable(_variable).toInt()>value.toInt();
case '>': check = script->variable(log, _variable).toInt()>value.toInt();
break;
default:;
}
log(QString("evaluated expression to ")+(check?"true":"false")+": "
+script->variable(_variable)+" "+_cmp+" "+value);
+script->variable(log, _variable)+" "+_cmp+" "+value);
}
if (check) return runScript(this, _script, script, frame);
else if (_else) return runScript(this, _else, script, frame);
if (check) return runScript(log, this, _script, script, frame);
else if (_else) return runScript(log, this, _else, script, frame);
return true;
}
private:
@ -2332,7 +2343,7 @@ class Check: public Command {
default:;
}
log("evaluated expression: "+value1+" "+_cmp+" "+value2);
if (!check) throw CheckFailed(value1, _cmp, value2);
if (!check) error(log, CheckFailed(value1, _cmp, value2));
return true;
}
private:
@ -2379,8 +2390,8 @@ class For: public Command {
}
bool execute(Script* script, QWebFrame* frame) {
Logger log(this, script);
Q_FOREACH(QString i, _vals.size()?_vals:commaSeparatedList(script->variable(_variable))) {
if (!runScript(this, _script, script, frame, QStringList()<<_variable, QStringList()<<i))
Q_FOREACH(QString i, _vals.size()?_vals:commaSeparatedList(script->variable(log, _variable))) {
if (!runScript(log, this, _script, script, frame, QStringList()<<_variable, QStringList()<<i))
return false;
}
return true;
@ -2444,7 +2455,7 @@ class OfflineStoragePath: public Command {
Logger log(this, script);
QDir path(_path);
if (!path.exists() && !path.mkpath(_path))
throw DirectoryCannotBeCreated(_path);
error(log, DirectoryCannotBeCreated(_path));
TestWebPage* page(dynamic_cast<TestWebPage*>(frame->page()));
page->settings()->setOfflineStoragePath(_path);
return true;
@ -2513,16 +2524,18 @@ class Include: public Command {
try {
cmd->_script = std::shared_ptr<Script>(new Script);
cmd->_script->parse(txt.split('\n'), cmd->_filename, 1, indent+1);
} catch (std::exception& e) {
} catch (Exception& e) {
throw ParseIncludeFailed(cmd->_filename, e.what());
}
return cmd;
}
bool execute(Script* script, QWebFrame* frame) try {
bool execute(Script* script, QWebFrame* frame) {
Logger log(this, script);
return runScript(this, _script, script, frame);
} catch (std::exception& e) {
throw ExecuteIncludeFailed(_filename, e.what());
try {
return runScript(log, this, _script, script, frame);
} catch (Exception& e) {
error(log, ExecuteIncludeFailed(_filename, e.what()));
}
}
private:
QString _filename;
@ -2624,27 +2637,27 @@ class Case: public Command {
+selector+" "+condition.cmp+" "+value);
} else {
switch (condition.cmp[0].toLatin1()) {
case '=': check = script->variable(_variable)==value;
case '=': check = script->variable(log, _variable)==value;
break;
case '!': check = script->variable(_variable)!=value;
case '!': check = script->variable(log, _variable)!=value;
break;
case '.': check = script->variable(_variable).contains(value);
case '.': check = script->variable(log, _variable).contains(value);
break;
case '^': check = !script->variable(_variable).contains(value);
case '^': check = !script->variable(log, _variable).contains(value);
break;
case '~': check =
script->variable(_variable).contains(QRegularExpression(value));
script->variable(log, _variable).contains(QRegularExpression(value));
break;
case '<': check = script->variable(_variable).toInt()<value.toInt();
case '<': check = script->variable(log, _variable).toInt()<value.toInt();
break;
case '>': check = script->variable(_variable).toInt()>value.toInt();
case '>': check = script->variable(log, _variable).toInt()>value.toInt();
break;
default:;
}
log(QString("evaluated expression to ")+(check?"true":"false")+": "
+script->variable(_variable)+" "+condition.cmp+" "+value);
+script->variable(log, _variable)+" "+condition.cmp+" "+value);
}
if (check) return runScript(this, condition.script, script, frame);
if (check) return runScript(log, this, condition.script, script, frame);
}
return true;
}
@ -2684,7 +2697,7 @@ class Fail: public Command {
}
bool execute(Script* script, QWebFrame*) {
Logger log(this, script);
throw TestFailed(script->replacevars(_text));
error(log, TestFailed(script->replacevars(_text)));
return true; // dummy
}
private:
@ -2725,7 +2738,7 @@ inline bool Screenshot::execute(Script* script, QWebFrame* frame) {
log("screenshots disabled");
return true;
}
QString filename(screenshot(line(), script->targetdir(),
QString filename(screenshot(log, line(), script->targetdir(),
script->testclass(),
script->replacevars(_filename), frame));
log["[[ATTACHMENT|"+filename+"]]"];
@ -2734,26 +2747,30 @@ inline bool Screenshot::execute(Script* script, QWebFrame* frame) {
inline Logger::Logger(Command* command, Script* script, bool showLines):
_command(command), _script(script) {
_previous = _script->command();
_script->command(command);
if (_command->log())
if (showLines)
_script->log("\\ "+_command->command(), _command);
else
_script->log("\\ "+_command->command().split('\n').first(), _command);
if (command) {
_previous = _script->command();
_script->command(command);
if (_command->log())
if (showLines)
_script->log("\\ "+_command->command(), _command);
else
_script->log("\\ "+_command->command().split('\n').first(), _command);
}
}
inline void Logger::operator()(QString txt) {
if (_command->log()) _script->log(" "+txt, _command);
if (!_command || _command->log()) _script->log(" "+txt, _command);
}
inline void Logger::operator[](QString txt) {
_script->plainlog(txt);
}
inline Logger::~Logger() {
if (_command->log()) _script->log("/ "+_command->tag(), _command);
_script->command(_previous);
if (_command) {
if (_command->log()) _script->log("/ "+_command->tag(), _command);
_script->command(_previous);
}
}
inline bool Command::runScript(Command* parentCommand,
inline bool Command::runScript(Logger& log, Command* parentCommand,
std::shared_ptr<Script> script,
Script* parent, QWebFrame* frame,
QStringList vars,
@ -2761,7 +2778,7 @@ inline bool Command::runScript(Command* parentCommand,
Script scriptCopy(*script); // only work with a copy of script
scriptCopy.set(*parent);
if (args.size()!=vars.size())
throw WrongNumberOfArguments(vars, args);
error(log, WrongNumberOfArguments(vars, args));
for (QStringList::iterator var(vars.begin()), arg(args.begin());
var<vars.end() && arg<args.end(); ++var, ++arg) {
parent->log("argument: "+*var+" = "+parent->replacevars(*arg),
@ -2778,13 +2795,13 @@ inline bool Command::runScript(Command* parentCommand,
parent, SLOT(parentlog(QString)));
parentCommand->_result = scriptCopy.result();
Q_FOREACH(QString key, scriptCopy.variables()) // copy new variables to parent
if (!vars.contains(key)) parent->set(key, scriptCopy.variable(key));
if (!vars.contains(key)) parent->set(key, scriptCopy.variable(log, key));
Q_FOREACH(QString key, scriptCopy.functions()) // copy new functions to parent
parent->function(key, scriptCopy.function(key));
parent->function(key, scriptCopy.function(log, key));
if (parentCommand->_result.size())
parent->log("result: "+parentCommand->_result);
return res;
} catch (const std::exception& x) {
} catch (const Exception& x) {
parent->addSignals(frame);
disconnect(&scriptCopy, SIGNAL(logging(QString)),
parent, SLOT(parentlog(QString)));

Loading…
Cancel
Save