new commands ignore and unignore to (un-) ignore signals

master
Marc Wäckerlin 7 years ago
parent 86cdc6777d
commit be6e52aeb0
  1. 1
      scripts/90wt-mode.el.in
  2. 8
      scripts/makefile.am
  3. 2
      scripts/wt-mode.el
  4. 159
      src/commands.hxx
  5. 2
      src/editor.hxx
  6. 6
      src/exceptions.hxx

@ -4,6 +4,7 @@
;;
;; Set up to autoload
(add-to-list 'load-path "@emacsdir@")
(autoload 'wt-mode "wt-mode" "Major mode for editing Webtester test scripts" t)
(setq auto-mode-alist
(cons '("\\.wt\\'" . wt-mode) auto-mode-alist))

@ -12,7 +12,13 @@ emacsdir = ${datadir}/emacs/site-lisp
dist_emacs_SCRIPTS = wt-mode.el
emacsconfdir = ${sysconfdir}/emacs/site-start.d
dist_emacsconf = 90wt-mode.el
emacsconf_DATA = 90wt-mode.el
EXTRA_DIST = 90wt-mode.el.in
90wt-mode.el: 90wt-mode.el.in
sed 's,@emacsdir@,'"${emacsdir}"',g' $< > $@
CLEANFILES = 90wt-mode.el
MAINTAINERCLEANFILES = makefile.in

@ -25,7 +25,7 @@
;; echo $(webrunner -h | sed -n 's, COMMAND: ,,p') | sed 's, ,\\\\|,g'
(defconst wt-font-lock-keywords
(list
'("^ *\\(auth\\|ca-certificate\\|call\\|case\\|check\\|clear-cookies\\|click\\|clicktype\\|client-certificate\\|do\\|download\\|echo\\|execute\\|exists\\|exit\\|expect\\|fail\\|for\\|function\\|if\\|while\\|ignoreto\\|include\\|label\\|load\\|not\\|offline-storage-path\\|open\\|screenshot\\|set\\|setvalue\\|sleep\\|testcase\\|testsuite\\|timeout\\|unset\\|upload\\) " . font-lock-builtin-face)
'("^ *\\(auth\\|ca-certificate\\|call\\|case\\|check\\|clear-cookies\\|click\\|clicktype\\|client-certificate\\|do\\|download\\|echo\\|execute\\|exists\\|exit\\|expect\\|fail\\|for\\|function\\|if\\|while\\|ignore\\|unignore\\|ignoreto\\|include\\|label\\|load\\|not\\|offline-storage-path\\|open\\|screenshot\\|set\\|setvalue\\|sleep\\|testcase\\|testsuite\\|timeout\\|unset\\|upload\\)\\b" . font-lock-builtin-face)
'("^ *#.*$" . font-lock-comment-face))
"Highlighting expressions for Webtester")

@ -25,6 +25,7 @@
#include <QRegularExpression>
#include <QNetworkCookieJar>
#include <QNetworkCookie>
#include <QSet>
#include <vector>
#include <queue>
#include <map>
@ -566,6 +567,7 @@ class Script: public QObject {
}
void cleanup() {
reset();
_ignore.clear();
_variables.clear();
_rvariables.clear();
_timeout = _defaultTimeout;
@ -822,15 +824,58 @@ class Script: public QObject {
_testsuites->last().attr("failures") = "0";
(*_testsuites)<<testsuite;
}
QStringList getSignals() {
QStringList res;
for (std::queue<Signal> sigs(_signals); !sigs.empty(); sigs.pop())
res+=sigs.front().first;
return res;
}
Signal getSignal() {
while (!_signals.size()) QCoreApplication::processEvents();
while (_signals.empty()) QCoreApplication::processEvents();
Signal res(_signals.front());
_signals.pop();
return res;
}
bool checkSignal(const QString& name, const QStringList& args = QStringList()) {
if (_ignore.contains(name)) {
log(QString("ignoring signal check for %1").arg(name));
return true;
}
while (_signals.empty()) QCoreApplication::processEvents();
Signal res(_signals.front());
if (res.first==name && (args.empty() || res.second==args)) {
_signals.pop();
return true;
}
return false;
}
QTimer& timer() {
return _timer;
}
void ignore(const Script& o) {
_ignore = o._ignore;
}
bool ignore(const QString& sig) {
return _ignore.contains(sig);
}
void ignore(QStringList sigs = QStringList()) {
if (sigs.empty())
sigs<<"loadFinished"<<"loadStarted"<<"frameChanged"<<"titleChanged"<<"urlChanged";
Q_FOREACH(const QString& sig, sigs) {
log("start ignoring: '"+sig+"'");
_ignore<<sig;
}
}
void unignore(QStringList sigs = QStringList()) {
if (sigs.empty())
sigs<<"loadFinished"<<"loadStarted"<<"frameChanged"<<"titleChanged"<<"urlChanged";
Q_FOREACH(const QString& sig, sigs) {
if (_ignore.contains(sig)) {
log("stop ignoring: '"+sig+"'");
_ignore.erase(_ignore.find(sig));
}
}
}
void ignoreto(const QString& l) {
_ignores.insert(l);
}
@ -859,6 +904,8 @@ class Script: public QObject {
_testsuites = o._testsuites;
_testclass = o._testclass;
_targetdir = o._targetdir;
_ignore = o._ignore;
_ignores = o._ignores;
_maxretries = o._maxretries;
_screenshots = o._screenshots;
_cout.clear();
@ -1043,6 +1090,10 @@ class Script: public QObject {
void javaScriptWindowObjectCleared() {
}
void loadFinished(bool ok) {
if (_ignore.contains("loadFinished")) {
log("ignored loadFinished");
return;
}
QString sig(ok?"true":"false");
if (_ignoreSignalsUntil.size() &&
_ignoreSignalsUntil != "loadFinished "+sig) {
@ -1054,6 +1105,10 @@ class Script: public QObject {
_signals.push(std::make_pair("loadFinished", QStringList(sig)));
}
void loadStarted() {
if (_ignore.contains("loadStarted")) {
log("ignored loadStarted");
return;
}
if (_ignoreSignalsUntil.size() && _ignoreSignalsUntil != "loadStarted") {
log("warning: ignored loadStarted, waiting for "+_ignoreSignalsUntil);
return;
@ -1063,11 +1118,23 @@ class Script: public QObject {
_signals.push(std::make_pair("loadStarted", QStringList()));
}
void frameChanged() {
if (_ignore.contains("frameChanged")) {
log("ignored frameChanged");
return;
}
}
void titleChanged(const QString&) {
if (_ignore.contains("titleChanged")) {
log("ignored titleChanged");
return;
}
//_signals.push(std::make_pair("titleChanged", QStringList(title)));
}
void urlChanged(const QUrl& url) {
if (_ignore.contains("urlChanged")) {
log("ignored urlChanged");
return;
}
if (_ignoreSignalsUntil.size() && _ignoreSignalsUntil != "urlChanged") {
log("warning: ignored urlChanged, waiting for "+_ignoreSignalsUntil);
return;
@ -1090,6 +1157,7 @@ class Script: public QObject {
Prototypes _prototypes;
Commands _script;
std::queue<Signal> _signals;
QSet<QString> _ignore; ///< signals to ignore
QTimer _timer;
int _step;
QSet<QString> _ignores;
@ -1236,21 +1304,21 @@ class Expect: public Command {
bool execute(Script* script, QWebFrame*) {
Logger log(this, script);
QStringList args(script->replacevars(_signal._args));
Script::Signal lastsignal(script->getSignal());
if (_signal._signal=="load") { // special signal load
while (lastsignal.first=="loadStarted") {
log("ignore signal: loadStarted");
lastsignal = script->getSignal(); // ignore optional loadStarted
while (!script->ignore("loadStarted") && script->checkSignal("loadStarted")) {
log("ignore signal: loadStarted"); // ignore optional loadStarted
}
if (lastsignal.first!="urlChanged" || (args.size() && lastsignal.second!=args))
error(log, WrongSignal("urlChanged", args, lastsignal));
lastsignal = script->getSignal();
if (!script->checkSignal("urlChanged", args))
error(log, WrongSignal("urlChanged", args, script->getSignal(),
script->getSignals()));
args=QStringList("true");
if (lastsignal.first!="loadFinished" || (lastsignal.second!=args))
error(log, WrongSignal("loadFinished", args, lastsignal));
if (!script->checkSignal("loadFinished", args))
error(log, WrongSignal("loadFinished", args, script->getSignal(),
script->getSignals()));
} else {
if (lastsignal.first!=_signal._signal || (args.size() && lastsignal.second!=args))
error(log, WrongSignal(_signal._signal, args, lastsignal));
if (!script->checkSignal(_signal._signal, args))
error(log, WrongSignal(_signal._signal, args, script->getSignal(),
script->getSignals()));
}
return true;
}
@ -2962,6 +3030,70 @@ class Auth: public Command {
QString _password;
};
class Ignore: public Command {
public:
QString tag() const {
return "ignore";
}
QString description() const {
return
tag()+" <signal1> <signal2> <...>"
"\n\n"
"Ignores a specific signal. It will not be placed in the queue "
"and any expect for this signal is always true. You can call "
"ignore with a space separated list of signal names. You cannot "
"specify signal arguments. An empty ignore ignores all signals.";
}
QString command() const {
return tag()+" "+_signals.join(" ");
}
std::shared_ptr<Command> parse(Script*, QString args,
QStringList&, QString, int, int) {
std::shared_ptr<Ignore> cmd(new Ignore());
cmd->_signals = args.split(' ', QString::SkipEmptyParts);
return cmd;
}
bool execute(Script* script, QWebFrame* frame) {
Logger log(this, script);
script->ignore(_signals);
return true;
}
private:
QStringList _signals;
};
class UnIgnore: public Command {
public:
QString tag() const {
return "unignore";
}
QString description() const {
return
tag()+" <signal1> <signal2> <...>"
"\n\n"
"Undo ignoring a specific signal. It will be placed in the queue "
"and any expect this signal checks the queue. You can call "
"unignore with a space separated list of signal names. You cannot "
"specify signal arguments. An empty ignore activates all signals.";
}
QString command() const {
return tag()+" "+_signals.join(" ");
}
std::shared_ptr<Command> parse(Script*, QString args,
QStringList&, QString, int, int) {
std::shared_ptr<UnIgnore> cmd(new UnIgnore());
cmd->_signals = args.split(' ', QString::SkipEmptyParts);
return cmd;
}
bool execute(Script* script, QWebFrame* frame) {
Logger log(this, script);
script->unignore(_signals);
return true;
}
private:
QStringList _signals;
};
/* Template:
class : public Command {
public:
@ -3067,6 +3199,7 @@ inline bool Command::runScript(Logger& log, Command* parentCommand,
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));
parent->ignore(scriptCopy); // copy ignore list
if (parentCommand->_result.size())
parent->log("result: "+parentCommand->_result);
return res;
@ -3118,6 +3251,8 @@ inline void Script::initPrototypes() {
add(new Case);
add(new Fail);
add(new Auth);
add(new Ignore);
add(new UnIgnore);
}
#endif

@ -19,7 +19,7 @@ class Highlighter: public QSyntaxHighlighter {
void include(QString);
public:
Highlighter(QTextDocument *parent): QSyntaxHighlighter(parent) {
QString commands="auth|ca-certificate|call|case|check|clear-cookies|click|clicktype|client-certificate|do|download|echo|execute|exists|exit|expect|fail|for|function|if|while|ignoreto|include|label|load|not|offline-storage-path|open|screenshot|set|setvalue|sleep|testcase|testsuite|timeout|unset|upload";
QString commands="auth|ca-certificate|call|case|check|clear-cookies|click|clicktype|client-certificate|do|download|echo|execute|exists|exit|expect|fail|for|function|if|while|ignore|unignore|ignoreto|include|label|load|not|offline-storage-path|open|screenshot|set|setvalue|sleep|testcase|testsuite|timeout|unset|upload";
_expressions<<Expression("^ *("+commands+")\\b").weight(QFont::Bold).fg(Qt::darkBlue)
<<Expression("^ *#.*$").weight(QFont::Bold).fg(Qt::black);
}

@ -68,10 +68,12 @@ class PossibleRetryLoad: public TestFailed {
class WrongSignal: public PossibleRetryLoad {
public:
WrongSignal(QString signal, QStringList args,
std::pair<QString, QStringList> received):
std::pair<QString, QStringList> received,
QStringList sigs):
PossibleRetryLoad
("expected: \""+signal+" "+args.join(' ')+"\"; "
"received: \""+received.first+" "+received.second.join(' ')+"\"") {
"received: \""+received.first+" "+received.second.join(' ')
+"\"; queue: "+sigs.join(", ")) {
}
};

Loading…
Cancel
Save