From 9335d5f6bbe68eb5ec8236a10749fef02a4c5eef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20W=C3=A4ckerlin?= Date: Sat, 9 May 2015 12:27:03 +0000 Subject: [PATCH] new commands testsuite and testcase --- ChangeLog | 7 ++ ax_check_qt.m4 | 33 ++++++++ ax_init_standard_project.m4 | 46 +++++++++-- bootstrap.sh | 96 +++++++++++++++-------- doc/makefile.amto | 9 +++ src/commands.hxx | 151 +++++++++++++++++++++++++++--------- src/testgui.hxx | 21 ++--- src/webrunner.cxx | 71 +++++++++++++---- 8 files changed, 329 insertions(+), 105 deletions(-) create mode 100644 doc/makefile.amto diff --git a/ChangeLog b/ChangeLog index e522bb1..2ad69c4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2015-05-08 15:34 marc + + * ChangeLog, ax_init_standard_project.m4, bootstrap.sh, + docker/Dockerfile, src/commands.hxx, src/exceptions.hxx, + src/testgui.hxx: new feature: if tatement for conditions in + functions + 2015-05-06 23:09 marc * ChangeLog, bootstrap.sh, doc/doxyfile.in, diff --git a/ax_check_qt.m4 b/ax_check_qt.m4 index ce7628b..61724b6 100644 --- a/ax_check_qt.m4 +++ b/ax_check_qt.m4 @@ -104,12 +104,24 @@ AC_DEFUN([AX_CHECK_QT], [ MOC_FLAGS+=" -DHAVE_$1=1 ${[$1]5_CFLAGS}" AM_CXXFLAGS+=" ${[$1]5_CFLAGS}" LIBS+=" ${[$1]5_LIBS}" + modules=${qt_modules//Qt/Qt5} + if test -z "$PKG_REQUIREMENTS"; then + PKG_REQUIREMENTS="${modules// /, }" + else + PKG_REQUIREMENTS="${PKG_REQUIREMENTS}, ${modules// /, }" + fi if test -n "${qt_modules_optional}"; then PKG_CHECK_MODULES([$1]5_OPTIONAL, [${qt_modules_optional//Qt/Qt5}], [ AM_CPPFLAGS+=" ${[$1]5_OPTIONAL_CFLAGS}" MOC_FLAGS+=" ${[$1]5_OPTIONAL_CFLAGS}" AM_CXXFLAGS+=" ${[$1]5_OPTIONAL_CFLAGS}" LIBS+=" ${[$1]5_OPTIONAL_LIBS}" + modules=${qt_modules_optional//Qt/Qt5} + if test -z "$PKG_REQUIREMENTS"; then + PKG_REQUIREMENTS="${modules// /, }" + else + PKG_REQUIREMENTS="${PKG_REQUIREMENTS}, ${modules// /, }" + fi ], [ AC_MSG_NOTICE([Not found: ${qt_modules_optional//Qt/Qt5}]) ]) @@ -122,12 +134,24 @@ AC_DEFUN([AX_CHECK_QT], [ MOC_FLAGS+=" -DHAVE_$1=1 ${$1_CFLAGS}" AM_CXXFLAGS+=" ${$1_CFLAGS}" LIBS+=" ${$1_LIBS}" + modules=${qt_modules} + if test -z "$PKG_REQUIREMENTS"; then + PKG_REQUIREMENTS="${modules// /, }" + else + PKG_REQUIREMENTS="${PKG_REQUIREMENTS}, ${modules// /, }" + fi if test -n "$3"; then PKG_CHECK_MODULES($1_OPTIONAL, [${qt_modules_optional}], [ AM_CPPFLAGS+=" ${$1_OPTIONAL_CFLAGS}" MOC_FLAGS+=" ${$1_OPTIONAL_CFLAGS}" AM_CXXFLAGS+=" ${$1_OPTIONAL_CFLAGS}" LIBS+=" ${$1_OPTIONAL_LIBS}" + modules=${qt_modules_optional} + if test -z "$PKG_REQUIREMENTS"; then + PKG_REQUIREMENTS="${modules// /, }" + else + PKG_REQUIREMENTS="${PKG_REQUIREMENTS}, ${modules// /, }" + fi ], [ AC_MSG_NOTICE([Not found: ${qt_modules_optional}]) ]) @@ -139,6 +163,7 @@ AC_DEFUN([AX_CHECK_QT], [ AC_SUBST(AM_CPPFLAGS) AC_SUBST(MOC_FLAGS) AC_SUBST(AM_CXXFLAGS) + AC_SUBST(PKG_REQUIREMENTS) AX_ADDITIONAL_QT_RULES_HACK=' ui_%.hxx: %.ui $(UIC) -o [$][@] $< @@ -191,3 +216,11 @@ AC_DEFUN([AX_REQUIRE_QT], [ AC_MSG_ERROR([Required Qt modules not found: $2]) fi ]) + + +# Omit Qt Keywords +# AX_QT_NO_KEYWORDS + +AC_DEFUN([AX_QT_NO_KEYWORDS], [ + AM_CPPFLAGS+=" -DQT_NO_KEYWORDS" +]) diff --git a/ax_init_standard_project.m4 b/ax_init_standard_project.m4 index 468a528..a882473 100644 --- a/ax_init_standard_project.m4 +++ b/ax_init_standard_project.m4 @@ -5,7 +5,7 @@ # define least version number from subversion's revision number: # it is taken modulo 256 due to a bug on Apple's MacOSX -m4_define(x_version, m4_esyscmd_s( +m4_define(x_least, m4_esyscmd_s( SVN_REVISION="ERROR-UNDEFINED-REVISION-to-be-built-in-subdirectory-of-svn-checkout" for path in . .. ../..; do if svn info $path 2>&1 > /dev/null; then @@ -15,7 +15,26 @@ m4_define(x_version, m4_esyscmd_s( fi done # Mac does not support LEAST > 255 - echo $ECHO_N x_major.$((x_minor+$SVN_REVISION/256)).$(($SVN_REVISION%256)) + echo $ECHO_N $(($SVN_REVISION%256)) +)) +# define version number from subversion's revision number: +# it is taken modulo 256 due to a bug on Apple's MacOSX +# add to x_minor if revision number is > 256 +m4_define(x_minor_fixed, m4_esyscmd_s( + SVN_REVISION="ERROR-UNDEFINED-REVISION-to-be-built-in-subdirectory-of-svn-checkout" + for path in . .. ../..; do + if svn info $path 2>&1 > /dev/null; then + SVN_REVISION=$(LANG= svn info $path | sed -n 's/Last Changed Rev: //p') + (cd $path && svn2cl) + break; + fi + done + # Mac does not support LEAST > 255 + echo $ECHO_N $((x_minor+$SVN_REVISION/256)) +)) +# setup version number +m4_define(x_version, m4_esyscmd_s( + echo $ECHO_N x_major.x_minor_fixed.x_least )) ## bugreport mail address is taken from in first line of AUTHORS @@ -81,7 +100,7 @@ AC_DEFUN([AX_SUBST], [ # m4_define(x_major, MAJOR_NUMBER) # project's major version # m4_define(x_minor, MINOR_NUMBER) # project's minor version # m4_include(ax_init_standard_project.m4) -# AC_INIT(x_package_name, x_major.x_minor.x_least, x_bugreport, x_package_name) +# AC_INIT(x_package_name, x_version, x_bugreport, x_package_name) # AM_INIT_AUTOMAKE([1.9 tar-pax]) # AX_INIT_STANDARD_PROJECT # @@ -105,7 +124,7 @@ AC_DEFUN([AX_INIT_STANDARD_PROJECT], [ AX_SUBST(DISTRO) BUILD_NUMBER=${BUILD_NUMBER:-1} AX_SUBST(BUILD_NUMBER) - BUILD_DATE=$(date +"%Y-%m-%d %H:%M %Z") + BUILD_DATE=$(LANG= date +"%a, %d %B %Y %H:%M:%S %z") AX_SUBST(BUILD_DATE) if test -f "${PROJECT_NAME}-logo.png"; then PROJECT_LOGO="${PROJECT_NAME}-logo.png" @@ -225,7 +244,7 @@ AC_DEFUN([AX_USE_LIBTOOL], [ # libtool versioning LIB_MAJOR=m4_eval(x_major+x_minor) LIB_MINOR=x_least - LIB_LEAST=x_minor + LIB_LEAST=x_minor_fixed LIB_VERSION="${LIB_MAJOR}:${LIB_MINOR}:${LIB_LEAST}" AM_LDFLAGS="-version-info ${LIB_VERSION}" AC_SUBST(AM_LDFLAGS) @@ -380,6 +399,11 @@ AC_DEFUN([AX_PKG_REQUIRE], [ AM_CPPFLAGS+=" ${$1_CFLAGS}" AM_CXXFLAGS+=" ${$1_CFLAGS}" LIBS+=" ${$1_LIBS}" + if test -z "$PKG_REQUIREMENTS"; then + PKG_REQUIREMENTS="$2" + else + PKG_REQUIREMENTS="${PKG_REQUIREMENTS}, $2" + fi ], [ AC_MSG_WARN([Recommended package $2 for feature $1 not installed]) if test -n "$4"; then @@ -411,6 +435,11 @@ AC_DEFUN([AX_PKG_REQUIRE], [ AM_CPPFLAGS+=" ${$1_CFLAGS}" AM_CXXFLAGS+=" ${$1_CFLAGS}" LIBS+=" ${$1_LIBS}" + if test -z "$PKG_REQUIREMENTS"; then + PKG_REQUIREMENTS="$pkg" + else + PKG_REQUIREMENTS="${PKG_REQUIREMENTS}, $pkg" + fi ], [ AC_MSG_WARN([Recommended package $pkg for feature $1 not installed]) ]) @@ -419,6 +448,7 @@ AC_DEFUN([AX_PKG_REQUIRE], [ ]) AC_SUBST(AM_CPPFLAGS) AC_SUBST(AM_CXXFLAGS) + AC_SUBST(PKG_REQUIREMENTS) if test -n "$3"; then old_CPPFLAGS=${CPPFLAGS} CPPFLAGS=" ${$1_CFLAGS} ${CPPFLAGS}" @@ -445,6 +475,11 @@ AC_DEFUN([AX_PKG_CHECK], [ AM_CPPFLAGS+=" ${$1_CFLAGS}" AM_CXXFLAGS+=" ${$1_CFLAGS}" LIBS+=" ${$1_LIBS}" + if test -z "$PKG_REQUIREMENTS"; then + PKG_REQUIREMENTS="m4_default([$2], [$1])" + else + PKG_REQUIREMENTS="${PKG_REQUIREMENTS}, m4_default([$2], [$1])" + fi ], [ HAVE_$1=0 ]) @@ -452,4 +487,5 @@ AC_DEFUN([AX_PKG_CHECK], [ AC_SUBST(HAVE_$1) AC_SUBST(AM_CPPFLAGS) AC_SUBST(AM_CXXFLAGS) + AC_SUBST(PKG_REQUIREMENTS) ]) diff --git a/bootstrap.sh b/bootstrap.sh index 7862656..82ab6df 100755 --- a/bootstrap.sh +++ b/bootstrap.sh @@ -22,28 +22,31 @@ configure=0 build=0 overwrite=0 rebuild=0 +rebuildfiles=() while test $# -gt 0; do case "$1" in (--configure|-c) configure=1;; (--build|-b) configure=1; build=1;; (--overwrite|-o) overwrite=1;; (--rebuild|-r) rebuild=1;; + (--rebuild-file|-f) shift; rebuildfiles+=("$1");; (--version|-v) echo "$Id$"; exit;; (--help|-h) less < rebild specific file (can be added multiple times) + --help, -h show this help + --version, -v show version and date of this file DESCRIPTION @@ -122,9 +125,15 @@ GENERATED FILES REBUILDING FILES - To rebuild all these files, just run "${MY_NAME} -o". You can also - remove and rebuild a single file by removing it from subversion, - just call "svn rm " and "${MY_NAME}" to rebuild file "". + To rebuild all these files, just run "${MY_NAME} -r". + + To copy only the files provided by this package, that means those + files you must never change, that means to update the build system + to the latest release, run "${MY_NAME} -o" + + You can also rebuild a list of singleany list of specific file files + by adding option "${MY_NAME} -f " to rebuild file + "". You can add option "-f" more than once. FILES TO EDIT @@ -216,7 +225,7 @@ done HEADER='## @id '"\$Id\$"' # -# This file has been added by '${MY_NAME}' on '$(date +"%Y-%m-%d %H:%M %Z")' +# This file has been added by '${MY_NAME}' on '$(LANG= date +"%a, %d %B %Y %H:%M:%S %z")' # Feel free to change it or even remove and rebuild it, up to your needs # ## 1 2 3 4 5 6 7 8 @@ -224,6 +233,10 @@ HEADER='## @id '"\$Id\$"' ' +notice() { + echo -e "\e[1;33m$*\e[0m" +} + run() { check=1 while test $# -gt 0; do @@ -256,6 +269,12 @@ testtag() { egrep -q '^ *'"$1" configure.ac } +contains() { + local e + for e in "${@:2}"; do [[ "$e" == "$1" ]] && return 0; done + return 1 +} + checkdir() { if ! test -d "$1"; then # create path run mkdir -p "$1" @@ -285,8 +304,10 @@ to() { esac shift; done - if checkfile "$1" && test $rebuild -eq 0; then # file already exists - return + if checkfile "$1" && test $rebuild -eq 0 \ + && ! contains "$1" "${rebuildfiles[@]}"; then + # file already exists and must not be rebuilt + return 1 fi checkdir "$(dirname ${1})" echo -en "\e[1m-> generating:\e[0m $1 ..." @@ -307,10 +328,13 @@ to() { run svn add "$1" run svn propset svn:keywords "Id" "$1" fi + return 0 } copy() { - if checkfile "$1" && test $overwrite -eq 0; then + if checkfile "$1" && test $overwrite -eq 0 \ + && ! contains "$1" "${rebuildfiles[@]}"; then + # file already exists and must not be rebuilt return fi run cp "${0%/*}/$1" "$1" @@ -347,14 +371,18 @@ copy ${MY_NAME} copy ax_init_standard_project.m4 copy ax_cxx_compile_stdcxx_11.m4 copy ax_check_qt.m4 -copy AUTHORS -if ! test -f configure.ac; then - to configure.ac <command(); + } + return result; + } + void run(QWebFrame* frame) { + run(frame, _testsuites, targetdir(), _screenshots, _maxretries); } - void run(QWebFrame* frame, xml::Node& testsuiteNode, + void run(QWebFrame* frame, std::shared_ptr testsuites, QString td = QString(), bool screenshots = true, int maxretries = 0) { - _internalTestsuiteNode = &testsuiteNode; - assert(_internalTestsuiteNode); + _testsuites = testsuites; _timeout = 20; // defaults to 20s _ignoreSignalsUntil.clear(); addSignals(frame); _screenshots = screenshots; + _maxretries = maxretries; _timer.setSingleShot(true); + targetdir(!td.isEmpty() + ? td + : _testsuites->children() + ? xmlstr(_testsuites->last().attr("name")) + : "attachments"); + if (!_testsuites->children()) { + xml::Node testsuite("testsuite"); + testsuite.attr("name") = "Unnamed Test Suite"; + (*_testsuites)<command(), true).toStdString(); + testcase.attr("classname") = xmlattr(_testclass, true).toStdString(); testcase.attr("name") = - xmlattr((*cmd)->tag(), true).toStdString(); + xmlattr((*cmd)->command(), true).toStdString(); if (!_ignores.size() || (*cmd)->tag()=="label") { // not ignored _timer.start(_timeout*1000); - testsuite(xmlstr(testsuiteNode.attr("name"))); - targetdir(!td.isEmpty() ? td : xmlstr(testsuiteNode.attr("name"))); try { if (!(*cmd)->execute(this, frame)) { _timer.stop(); @@ -501,7 +511,7 @@ class Script: public QObject { xmlattr(_cerr).toStdString()); _cout.clear(); _cerr.clear(); - testsuiteNode<last()<line(), targetdir(), - QFileInfo(testsuite()).baseName(), + _testclass, QString("retry-%1") .arg((ulong)retries, 2, 10, QLatin1Char('0')), @@ -563,7 +573,7 @@ class Script: public QObject { xmlattr(_cerr).toStdString()); _cout.clear(); _cerr.clear(); - testsuiteNode<last()<last()<line()); if (screenshots) @@ -582,22 +592,20 @@ class Script: public QObject { { QString filename(Screenshot::sourceHtml ((*cmd)->line(), targetdir(), - QFileInfo(testsuite()).baseName(), + _testclass, "error", frame)); plainlog("[[ATTACHMENT|"+filename+"]]"); } { QString filename(Screenshot::screenshot ((*cmd)->line(), targetdir(), - QFileInfo(testsuite()).baseName(), + _testclass, "error", frame)); plainlog("[[ATTACHMENT|"+filename+"]]"); } } catch (... ) {} // ignore exception in screenshot - _internalTestsuiteNode = 0; throw; } } - _internalTestsuiteNode = 0; removeSignals(frame); if (!_signals.empty()) throw UnhandledSignals(_signals); } @@ -613,18 +621,26 @@ class Script: public QObject { bool screenshots() { return _screenshots; } - void testsuite(QString name) { - _testsuite = name; - } - QString testsuite() { - return _testsuite; - } void targetdir(QString name) { _targetdir = name; } QString targetdir() { return _targetdir; } + void testclass(QString tc) { + _testclass = tc; + } + QString testclass() { + return _testclass; + } + void testsuite(QString name) { + xml::Node testsuite("testsuite"); + testsuite.attr("name") = xmlattr(name, true).toStdString(); + testsuite.attr("timestamp") = + QDateTime::currentDateTime().toString(Qt::ISODate).toStdString(); + _testsuites->last().attr("failures") = "0"; + (*_testsuites)< _variables; ///< variable mapping QMap _rvariables; ///< reverse variable mapping QMap > _functions; int _timeout; ClickType _clicktype; - QString _testsuite; QString _targetdir; - xml::Node* _internalTestsuiteNode; ///< only valid within run + std::shared_ptr _testsuites; ///< only valid within run + QString _testclass; }; class Do: public Command { @@ -1892,7 +1910,8 @@ class If: public Command { "Match allows a regular expression."; } QString command() const { - return tag(); + return tag()+" "+_variable+" "+QString(_cmp)+" "+_value + +(_script.get()?"\n"+_script->print().join("\n "):""); } std::shared_ptr parse(Script*, QString args, QStringList& in, int) { @@ -1934,6 +1953,64 @@ class If: public Command { std::shared_ptr