/*! @file @id $Id$ */ // 1 2 3 4 5 6 7 8 // 45678901234567890123456789012345678901234567890123456789012345678901234567890 #ifndef COMMANDS_HXX #define COMMANDS_HXX #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_CXXABI_H #include inline QString demangle(const char* mangled) { int status; std::unique_ptr result( abi::__cxa_demangle(mangled, 0, 0, &status), free); return QString(result.get() ? result.get() : mangled); } #else inline QString demangle(const char* mangled) { return QString(mangled); } #endif namespace std { template class optional { private: T* _opt; bool _set; public: optional(): _opt(0), _set(false) { } optional(const T& other): _opt(new T(other)), _set(true) { } ~optional() { if (_set) delete _opt; } optional& operator=(const T& other) { if (_set) delete _opt; _set = true; _opt = new T(other); return *this; } T* operator->() { return _opt; } T& operator*() { return *_opt; } const T* operator->() const { return _opt; } const T& operator*() const { return *_opt; } operator bool() const { return _set; } }; } class Script; class Command; class Function; class Logger { public: Logger(Command* command, Script* script, bool showLines = true); void operator[](QString txt); void operator()(QString txt); ~Logger(); private: Command* _command; Command* _previous; Script* _script; }; class Command: public QObject { Q_OBJECT; public: 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, int) = 0; virtual bool execute(Script*, QWebFrame*) = 0; static void error(Logger& log, const Exception& e) { log(QString(" FAILED[")+demangle(typeid(e).name())+"]: "+e.what()); throw e; } virtual int steps(Script* parent) { return 1; } void line(int linenr) { _line = linenr; } int line() const { return _line; } void file(QString filename) { _file = filename; } QString file() const { return _file; } void indent(int i) { _indent = i; } int indent() const { return _indent; } bool log() { return _log; } void log(bool l) { _log = l; } QString result() { return _result; } virtual bool isTestcase() { return true; } static void realMouseClick(Logger& log, QWebFrame* frame, Script* script, QString selector); static void realMouseClick(const QWebElement& element) { QWidget* web(element.webFrame()->page()->view()); QRect elGeom=element.geometry(); QPoint elPoint=elGeom.center(); int elX=elPoint.x(); int elY=elPoint.y(); int webWidth=web->width(); int webHeight=web->height(); int pixelsToScrolRight=0; int pixelsToScrolDown=0; if (elX>webWidth) pixelsToScrolRight = //the +10 scrolls a bit further elX-webWidth+elGeom.width()/2+10; if (elY>webHeight) pixelsToScrolDown = //the +10 scrolls a bit further elY-webHeight+elGeom.height()/2+10; element.webFrame()->setScrollBarValue(Qt::Horizontal, pixelsToScrolRight); element.webFrame()->setScrollBarValue(Qt::Vertical, pixelsToScrolDown); QPoint pointToClick(elX-pixelsToScrolRight, elY-pixelsToScrolDown); QMouseEvent pressEvent(QMouseEvent::MouseButtonPress, pointToClick, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier); QCoreApplication::sendEvent(web, &pressEvent); QMouseEvent releaseEvent(QMouseEvent::MouseButtonRelease, pointToClick, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier); QCoreApplication::sendEvent(web, &releaseEvent); QCoreApplication::processEvents(); } static void sleep(int s) { QTime dieTime= QTime::currentTime().addSecs(s); while (QTime::currentTime() subParser(Script* parent, const QStringList& in, const QString& file, int line, int indent); bool runScript(Logger& log, Command* parentCommand, std::shared_ptr