more improve expect load; better logging in case of exception
This commit is contained in:
211
src/commands.hxx
211
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;
|
||||
}
|
||||
@@ -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;
|
||||
@@ -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,
|
||||
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,7 +2098,7 @@ class Call: public Command {
|
||||
}
|
||||
bool execute(Script* script, QWebFrame* frame) {
|
||||
Logger log(this, script);
|
||||
return script->function(_name)->call(this, script->replacevars(_args),
|
||||
return script->function(log, _name)->call(log, this, script->replacevars(_args),
|
||||
script, frame);
|
||||
}
|
||||
public:
|
||||
@@ -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,6 +2747,7 @@ inline bool Screenshot::execute(Script* script, QWebFrame* frame) {
|
||||
|
||||
inline Logger::Logger(Command* command, Script* script, bool showLines):
|
||||
_command(command), _script(script) {
|
||||
if (command) {
|
||||
_previous = _script->command();
|
||||
_script->command(command);
|
||||
if (_command->log())
|
||||
@@ -2741,19 +2755,22 @@ inline Logger::Logger(Command* command, Script* script, bool 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) {
|
||||
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)));
|
||||
|
Reference in New Issue
Block a user