diff options
Diffstat (limited to 'libqsystemtest')
34 files changed, 0 insertions, 9780 deletions
diff --git a/libqsystemtest/DESCRIPTION b/libqsystemtest/DESCRIPTION deleted file mode 100644 index 04f1e0e..0000000 --- a/libqsystemtest/DESCRIPTION +++ /dev/null @@ -1 +0,0 @@ -Core functionality of the QtUitest script interpreter. diff --git a/libqsystemtest/customtestcontrol.cpp b/libqsystemtest/customtestcontrol.cpp deleted file mode 100644 index 0ba2573..0000000 --- a/libqsystemtest/customtestcontrol.cpp +++ /dev/null @@ -1,68 +0,0 @@ -#include "customtestcontrol.h" - -#include <QDebug> -#include <QProcess> -#include <QApplication> - -using namespace Qt4Test; - -CustomTestControl::CustomTestControl() - : TestControl() -{ - -} - -CustomTestControl::~CustomTestControl() -{ - -} - -bool CustomTestControl::deviceConfiguration( QString &reply ) -{ - return false; -} - -bool CustomTestControl::startApplication( const QString &application, const QStringList &arguments, - bool styleQtUITest, const QStringList &environment, QString &reply ) -{ - QProcess proc; - QStringList args = arguments; - args.prepend(application); - static QByteArray startProcess = qgetenv("QTUITEST_START_PROCESS"); - if (startProcess.isEmpty()) { - qDebug() << QString("Could not start remote process '%1', QTUITEST_START_PROCESS not defined.").arg(application); - return false; - } - - proc.start(startProcess, args); - if (!proc.waitForFinished(10000)) { - proc.kill(); - if (!proc.waitForFinished(5000)) - return false; - } - - return true; -} - -bool CustomTestControl::killApplication( const QString &application, QString &reply ) -{ - // ensure that we stop any running remote applications - QProcess proc; - QStringList args; - args << application; - args << QString("-style=qtuitest"); - - static QByteArray stopProcess = qgetenv("QTUITEST_STOP_PROCESS"); - if (stopProcess.isEmpty()) { - qDebug() << QString("Could not stop remote process '%1', QTUITEST_STOP_PROCESS not defined.").arg(application); - return false; - } - - proc.start(stopProcess, args); - if (!proc.waitForFinished(10000)) { - proc.kill(); - if (!proc.waitForFinished(5000)) - return false; - } - return true; -} diff --git a/libqsystemtest/customtestcontrol.h b/libqsystemtest/customtestcontrol.h deleted file mode 100644 index 0cad4af..0000000 --- a/libqsystemtest/customtestcontrol.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef CUSTOMTESTCONTROL_H -#define CUSTOMTESTCONTROL_H - -#include "testcontrol.h" - -namespace Qt4Test { -class CustomTestControl : public TestControl -{ - Q_OBJECT -public: - CustomTestControl(); - virtual ~CustomTestControl(); - - bool deviceConfiguration( QString &reply ); - - bool startApplication( const QString &application, const QStringList &arguments, - bool styleQtUITest, const QStringList &environment, QString &reply ); - bool killApplication( const QString &application, QString &reply ); -}; - -} - -#endif // CUSTOMTESTCONTROL_H diff --git a/libqsystemtest/desktoptestcontrol.cpp b/libqsystemtest/desktoptestcontrol.cpp deleted file mode 100644 index f41559a..0000000 --- a/libqsystemtest/desktoptestcontrol.cpp +++ /dev/null @@ -1,73 +0,0 @@ -#include "desktoptestcontrol.h" - -#include <QDebug> -#include <QProcess> - - -using namespace Qt4Test; - -DesktopTestControl* DesktopTestControl::instance() -{ - static DesktopTestControl instance; - return &instance; -} - -DesktopTestControl::DesktopTestControl() - : TestControl() -{ - proc = 0; -} - -DesktopTestControl::~DesktopTestControl() -{ - -} - -bool DesktopTestControl::deviceConfiguration( QString &reply ) -{ - return false; -} - -bool DesktopTestControl::startApplication( const QString &application, const QStringList &arguments, - bool styleQtUITest, const QStringList &environment, QString &reply ) -{ - proc = new Qt4Test::TestProcess(this); - - proc->setEnvironment(environment); -// FIXME proc->test = this; - QStringList args = arguments; - if (styleQtUITest) { - args << "-style"; - args << "qtuitest"; - } - - QByteArray defArgs = qgetenv("QTUITEST_DEFAULT_AUT_ARGS"); - if (defArgs.length()) { - QList<QByteArray> defaultArgs = defArgs.split(' '); - foreach (QByteArray arg, defaultArgs) { - args << arg; - } - } - - proc->start(application, args); - if (!proc->waitForStarted()) { - reply = QString("Failed to start process '%1': %2").arg(application).arg(proc->errorString()); - delete proc; - return false; - } - return true; -} - -bool DesktopTestControl::killApplication( const QString &application, QString &reply ) -{ - if (!proc) - return false; - - proc->terminate(); - if (!proc->waitForFinished(5000)) { - proc->kill(); - proc->waitForFinished(5000); - } - return true; -} - diff --git a/libqsystemtest/desktoptestcontrol.h b/libqsystemtest/desktoptestcontrol.h deleted file mode 100644 index 9b1a301..0000000 --- a/libqsystemtest/desktoptestcontrol.h +++ /dev/null @@ -1,120 +0,0 @@ -#ifndef DESKTOPTESTCONTROL_H -#define DESKTOPTESTCONTROL_H - -#include "testcontrol.h" -#include "qsystemtest.h" - -#include <QProcess> - -namespace Qt4Test { - -class TestProcess : public QProcess -{ - Q_OBJECT - public: - TestProcess(QObject *parent = 0) - : QProcess(parent) - , env() - , test(0) - { - connect(this,SIGNAL(readyReadStandardError()),this,SLOT(error())); - connect(this,SIGNAL(readyReadStandardOutput()),this,SLOT(output())); - connect(this,SIGNAL(finished(int,QProcess::ExitStatus)), - this,SLOT(deleteLater())); - } - - QStringList env; - QSystemTest* test; - - private slots: - void output() - { - QByteArray text = readAllStandardOutput(); - if (!test) return; - - while (text.endsWith("\n")) text.chop(1); - QList<QByteArray> lines = text.split('\n'); - test->applicationStandardOutput(lines); - } - - void error() - { - QByteArray text = readAllStandardError(); - if (!test) return; - - while (text.endsWith("\n")) text.chop(1); - QList<QByteArray> lines = text.split('\n'); - test->applicationStandardError(lines); - } - - protected: - virtual void setupChildProcess() - { - foreach (QString const& e, env) { - int equals = e.indexOf('='); - if (equals == -1) continue; - QString key = e.left(equals); - QString value = e.mid(equals+1); - prependToEnv(key.toLocal8Bit(), value.toLocal8Bit()); - } - } - - private: - void prependToEnv(QByteArray const& key, QByteArray const& value) - { - // Environment variables which are a colon-separated list (like PATH) - static const QList<QByteArray> pathlike = QList<QByteArray>() - << "LD_LIBRARY_PATH" - ; - - // Environment variables which can be silently clobbered - static const QList<QByteArray> clobber = QList<QByteArray>() - << "DISPLAY" - ; - - QByteArray current = qgetenv(key.constData()); - QByteArray set = value; - if (!current.isEmpty()) { - if (pathlike.contains(key)) { - set = set + ":" + current; - } else if (clobber.contains(key)) { - } else { - // Cannot use qWarning because we are in a child process and we will pass - // through message handlers twice - fprintf(stderr, "Environment variable %s is already set (to \"%s\"); " - "qtuitestrunner will clobber it (with \"%s\") when starting test " - "process!" - ,key.constData() - ,current.constData() - ,set.constData() - ); - } - } -#ifndef Q_OS_WIN - setenv(key.constData(), set.constData(), 1); -#endif - } -}; - - -class DesktopTestControl : public TestControl -{ - Q_OBJECT -public: - static DesktopTestControl* instance(); - DesktopTestControl(); - virtual ~DesktopTestControl(); - - bool deviceConfiguration( QString &reply ); - - bool startApplication( const QString &application, const QStringList &arguments, - bool styleQtUITest, const QStringList &environment, QString &reply ); - bool killApplication( const QString &application, QString &reply ); - -private: - TestProcess* proc; -}; - -} - -#endif // DESKTOPTESTCONTROL_H diff --git a/libqsystemtest/failuredlg.ui b/libqsystemtest/failuredlg.ui deleted file mode 100644 index b8089d4..0000000 --- a/libqsystemtest/failuredlg.ui +++ /dev/null @@ -1,95 +0,0 @@ -<ui version="4.0" > - <class>FailureDlg</class> - <widget class="QDialog" name="FailureDlg" > - <property name="geometry" > - <rect> - <x>0</x> - <y>0</y> - <width>482</width> - <height>302</height> - </rect> - </property> - <property name="windowTitle" > - <string>Failure Message</string> - </property> - <layout class="QVBoxLayout" > - <property name="margin" > - <number>9</number> - </property> - <property name="spacing" > - <number>6</number> - </property> - <item> - <layout class="QVBoxLayout" > - <property name="margin" > - <number>0</number> - </property> - <property name="spacing" > - <number>6</number> - </property> - <item> - <widget class="QLabel" name="label" > - <property name="text" > - <string>Please describe how the test failed. Where relevant, refer to the manual verification steps. Your message will be appended to the test log.</string> - </property> - <property name="textFormat" > - <enum>Qt::PlainText</enum> - </property> - <property name="wordWrap" > - <bool>true</bool> - </property> - </widget> - </item> - <item> - <widget class="QTextEdit" name="failureEdit" /> - </item> - <item> - <widget class="QDialogButtonBox" name="buttonBox" > - <property name="orientation" > - <enum>Qt::Horizontal</enum> - </property> - <property name="standardButtons" > - <set>QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok</set> - </property> - </widget> - </item> - </layout> - </item> - </layout> - </widget> - <resources/> - <connections> - <connection> - <sender>buttonBox</sender> - <signal>accepted()</signal> - <receiver>FailureDlg</receiver> - <slot>accept()</slot> - <hints> - <hint type="sourcelabel" > - <x>258</x> - <y>291</y> - </hint> - <hint type="destinationlabel" > - <x>157</x> - <y>274</y> - </hint> - </hints> - </connection> - <connection> - <sender>buttonBox</sender> - <signal>rejected()</signal> - <receiver>FailureDlg</receiver> - <slot>reject()</slot> - <hints> - <hint type="sourcelabel" > - <x>326</x> - <y>291</y> - </hint> - <hint type="destinationlabel" > - <x>286</x> - <y>274</y> - </hint> - </hints> - </connection> - </connections> -</ui> diff --git a/libqsystemtest/libqsystemtest.pro b/libqsystemtest/libqsystemtest.pro deleted file mode 100644 index cbc59fb..0000000 --- a/libqsystemtest/libqsystemtest.pro +++ /dev/null @@ -1,79 +0,0 @@ -DEFINES += QSYSTEMTEST_TARGET - -FORMS +=\ - manualverificationdlg.ui \ - failuredlg.ui \ - recorddlg.ui - -SEMI_PRIVATE_HEADERS += \ - qsystemtestmaster_p.h \ - qtestremote_p.h \ - qtestprotocol_p.h \ - qtestverifydlg_p.h - -HEADERS +=\ - qabstracttest.h \ - qsystemtest.h \ - qtestide.h \ - testcontrol.h \ - maemotestcontrol.h \ - meegotestcontrol.h \ - symbiantestcontrol.h \ - desktoptestcontrol.h \ - customtestcontrol.h - -SOURCES +=\ - qabstracttest.cpp \ - qtestide.cpp \ - qtestremote.cpp \ - qtestverifydlg.cpp \ - qsystemtest.cpp \ - qsystemtest_p.cpp \ - qsystemtestmaster.cpp \ - qtestprotocol.cpp \ - testcontrol.cpp \ - maemotestcontrol.cpp \ - meegotestcontrol.cpp \ - symbiantestcontrol.cpp \ - desktoptestcontrol.cpp \ - customtestcontrol.cpp - -VPATH+=$$PWD -INCLUDEPATH+=$$PWD -INCLUDEPATH+=$$SRCROOT -INCLUDEPATH+=$$SRCROOT/botan/build -INCLUDEPATH+=$$SRCROOT/coreplugin -DEPENDPATH+=$$SRCROOT - -TEMPLATE=lib -TARGET=qsystemtest -TARGET=$$qtLibraryTarget($$TARGET) -HEADERS*=$$SEMI_PRIVATE_HEADERS $$PRIVATE_HEADERS -CONFIG+=qtestlib -QT+=network script -LIBS+=-L$$BUILDROOT/lib -lBotan -lCore - -unix:!symbian { - DESTDIR=$$BUILDROOT/lib - target.path=$$[QT_INSTALL_LIBS] - INSTALLS+=target -} - -symbian { - TARGET.EPOCALLOWDLLDATA=1 - TARGET.CAPABILITY += AllFiles ReadDeviceData ReadUserData SwEvent WriteUserData - LIBS+=-L$$OUT_PWD -lws32 -leuser -lcone -} - -win32 { - target.path=$$[QT_INSTALL_BINS] - INSTALLS+=target - !equals(QMAKE_CXX, "g++") { - DEFINES+=strcasecmp=_stricmp - } -} - -mac { - DEFINES+=sighandler_t=sig_t -} - diff --git a/libqsystemtest/maemotestcontrol.cpp b/libqsystemtest/maemotestcontrol.cpp deleted file mode 100644 index 074767d..0000000 --- a/libqsystemtest/maemotestcontrol.cpp +++ /dev/null @@ -1,261 +0,0 @@ -#include "maemotestcontrol.h" - -#include <QTime> -#include <QTimer> -#include <QApplication> -#include <QDebug> - -namespace Core { - class SshConnection; - class SshRemoteProcess; -} // namespace Core - -using namespace Core; - -namespace Qt4Test { - -MaemoTestControl::MaemoTestControl( Core::SshConnectionParameters &sshParam ) - : TestControl() -{ - ssh_param = sshParam; - control_mode = Idle; -} - -MaemoTestControl::~MaemoTestControl() -{ -} - -bool MaemoTestControl::deviceConfiguration( QString &reply ) -{ - runBlockingCommand( ConfigCheck, "", 10000); - reply = reply_txt; - return reply_ok; -} - -bool MaemoTestControl::runCustomCommand( const QString &cmd, int timeout, QString &reply ) -{ - runBlockingCommand( CustomCommand, cmd, timeout); - reply = reply_txt; - return reply_ok; -} - -bool MaemoTestControl::runCustomBlockingCommand( const QString &cmd, int timeout, QString &reply ) -{ - runBlockingCommand( CustomBlockingCommand, cmd, timeout); - reply = reply_txt; - return reply_ok; -} - -void MaemoTestControl::runBlockingCommand( MaemoTestControlMode mode, const QString &cmd, int timeout) -{ - reply_txt = ""; - reply_ok = true; - m_cmd = cmd; - control_mode = mode; - if (initConnection()) - waitForCommandToFinish(timeout); - cleanupConnection(); -} - -bool MaemoTestControl::startApplication( const QString &application, const QStringList &arguments, - bool styleQtUITest, const QStringList &environment, QString &reply ) -{ - Q_UNUSED(environment); - Q_UNUSED(arguments); - // for Maemo5 applications need to be run with run-standalone.sh - // however for Maemo6 we still need to set the variables - // in .profile eg DISPLAY=:0 - QString cmd = QString("( " - "if [ -x /usr/bin/run-standalone.sh ]; then " - "%1 /usr/bin/run-standalone.sh %2 %3; " - "else " - ". $HOME/.profile; " - "%1 %2 %3; " - "fi )") - .arg(environment.join(" ")) - .arg(application) - .arg(styleQtUITest?"-style qtuitest":""); - - runBlockingCommand( CustomCommand, cmd, 10000); - reply = reply_txt; - return reply_ok; -} - -bool MaemoTestControl::killApplication( const QString &application, QString &reply ) -{ -// if (m_testProcess) { -// m_testProcess->kill(); -// } - - return runCustomCommand( "killall " + application, 1000, reply); -} - -void MaemoTestControl::waitForCommandToFinish(int timeout) -{ - QTime t; - t.start(); - while (t.elapsed() < 10000 && control_mode != Idle) { - qApp->processEvents(); - } - if (control_mode != Idle) { - reply_ok = false; - reply_txt += "Command timed out"; - } -} - -bool MaemoTestControl::initConnection() -{ - if (m_testProcess) { - reply_ok = false; - reply_txt = "Process existed already"; - return false; - } - - reply_ok = true; - m_deviceTestOutput = ""; - m_connection = SshConnection::create(); - connect(m_connection.data(), SIGNAL(connected()), - this, SLOT(handleConnected())); - connect(m_connection.data(), SIGNAL(error(SshError)), - this, SLOT(handleConnectionError())); - - m_connection->connectToHost(ssh_param); - - return true; -} - -void MaemoTestControl::handleConnected() -{ - if (!m_connection) { - reply_ok = false; - reply_txt += "Invalid connection\n"; - return; - } - - if (control_mode == ConfigCheck) { - QLatin1String sysInfoCmd("uname -rsm"); - QLatin1String qtInfoCmd("dpkg -l |grep libqt " - "|sed 's/[[:space:]][[:space:]]*/ /g' " - "|cut -d ' ' -f 2,3 |sed 's/~.*//g'"); - QString command(sysInfoCmd + " && " + qtInfoCmd); - m_testProcess = m_connection->createRemoteProcess(command.toUtf8()); - } else if (control_mode == CustomCommand || control_mode == CustomBlockingCommand) { - m_testProcess = m_connection->createRemoteProcess(m_cmd.toUtf8()); - } - - QObject::connect(m_testProcess.data(), SIGNAL(closed(int)), this, - SLOT(handleProcessFinished(int)), Qt::DirectConnection); - connect(m_testProcess.data(), SIGNAL(outputAvailable(QByteArray)), this, - SLOT(processSshOutput(QByteArray)), Qt::DirectConnection); - - m_testProcess->start(); - - if (control_mode == CustomCommand) - QTimer::singleShot(500,this,SLOT(cleanupConnection())); -} - -void MaemoTestControl::handleConnectionError() -{ - reply_ok = false; - - if (!m_connection) { - reply_txt += "Invalid connection\n"; - } else { - reply_txt += tr("Could not connect to host: %1:%2 %3 %4\n%5\n") - .arg(ssh_param.host) - .arg(ssh_param.port) - .arg(ssh_param.uname) - .arg(ssh_param.pwd) - .arg(m_connection->errorString()); - } - cleanupConnection(); -} - -void MaemoTestControl::handleProcessFinished(int exitStatus) -{ - Q_ASSERT(exitStatus == SshRemoteProcess::FailedToStart - || exitStatus == SshRemoteProcess::KilledBySignal - || exitStatus == SshRemoteProcess::ExitedNormally); - - if (!m_testProcess) { - reply_ok = false; - reply_txt += "Invalid process\n"; - return; - } - - if (exitStatus != SshRemoteProcess::ExitedNormally - || m_testProcess->exitCode() != 0) { - reply_ok = false; - reply_txt += m_deviceTestOutput; - reply_txt += tr("Remote process failed: %1\n") - .arg(m_testProcess->errorString()); - } else if (control_mode == ConfigCheck) { - const QString &output = parseOutput(); - if (!m_qtVersionOk) { - reply_txt += tr("Qt version mismatch! " - " Expected Qt on device: 4.6.2 or later.\n"); - } - reply_txt += output; - } else if (control_mode == CustomCommand || control_mode == CustomBlockingCommand) { - reply_txt += m_deviceTestOutput; - } - - cleanupConnection(); -} - -void MaemoTestControl::cleanupConnection() -{ - if (m_testProcess) - disconnect(m_testProcess.data(), 0, this, 0); - if (m_connection) - disconnect(m_connection.data(), 0, this, 0); - control_mode = Idle; - m_testProcess.clear(); - m_connection.clear(); -} - -void MaemoTestControl::processSshOutput(const QByteArray &output) -{ - m_deviceTestOutput.append(QString::fromUtf8(output)); -} - -QString MaemoTestControl::parseOutput() -{ - if (control_mode == ConfigCheck) { - m_qtVersionOk = false; - - QString output; - const QRegExp unamePattern(QLatin1String("Linux (\\S+)\\s(\\S+)")); - int index = unamePattern.indexIn(m_deviceTestOutput); - if (index == -1) { - output = tr("Device configuration test failed: Unexpected output:\n%1") - .arg(m_deviceTestOutput); - return output; - } - - output = tr("Hardware architecture: %1\n").arg(unamePattern.cap(2)); - output.append(tr("Kernel version: %1\n").arg(unamePattern.cap(1))); - const QRegExp dkpgPattern(QLatin1String("libqt\\S+ (\\d)\\.(\\d)\\.(\\d)")); - index = dkpgPattern.indexIn(m_deviceTestOutput); - if (index == -1) { - output.append(tr("No Qt packages installed.")); - return output; - } - - output.append(tr("List of installed Qt packages:") + QLatin1Char('\n')); - do { - output.append(QLatin1Char('\t') + dkpgPattern.cap(0) - + QLatin1Char('\n')); - index = dkpgPattern.indexIn(m_deviceTestOutput, index + 1); - if (!m_qtVersionOk && QT_VERSION_CHECK(dkpgPattern.cap(1).toInt(), - dkpgPattern.cap(2).toInt(), dkpgPattern.cap(3).toInt()) >= 0x040602) { - m_qtVersionOk = true; - } - } while (index != -1); - return output; - } - - return ""; -} - -} diff --git a/libqsystemtest/maemotestcontrol.h b/libqsystemtest/maemotestcontrol.h deleted file mode 100644 index 4866890..0000000 --- a/libqsystemtest/maemotestcontrol.h +++ /dev/null @@ -1,54 +0,0 @@ -#ifndef MAEMOTESTCONTROL_H -#define MAEMOTESTCONTROL_H - -#include "testcontrol.h" -#include <coreplugin/ssh/sshconnection.h> -#include <coreplugin/ssh/sshremoteprocess.h> - -namespace Qt4Test { -class MaemoTestControl : public TestControl -{ - Q_OBJECT -public: - MaemoTestControl( Core::SshConnectionParameters &sshParam ); - virtual ~MaemoTestControl(); - - bool deviceConfiguration( QString &reply ); - - bool startApplication( const QString &application, const QStringList &arguments, - bool styleQtUITest, const QStringList &environment, QString &reply ); - bool killApplication( const QString &application, QString &reply ); - -protected: - bool runCustomCommand( const QString &cmd, int timeout, QString &reply ); - bool runCustomBlockingCommand( const QString &cmd, int timeout, QString &reply ); - -private slots: - void cleanupConnection(); - - void processSshOutput(const QByteArray &output); - void handleConnected(); - void handleConnectionError(); - void handleProcessFinished(int exitStatus); - -private: - bool initConnection(); - QString parseOutput(); - void waitForCommandToFinish(int timeout); - - enum MaemoTestControlMode {Idle, ConfigCheck, CustomCommand, CustomBlockingCommand}; - MaemoTestControlMode control_mode; - void runBlockingCommand( MaemoTestControlMode mode, const QString &cmd, int timeout); - - QSharedPointer<Core::SshConnection> m_connection; - QSharedPointer<Core::SshRemoteProcess> m_testProcess; - Core::SshConnectionParameters ssh_param; - QString m_deviceTestOutput; - bool m_qtVersionOk; - bool reply_ok; - QString reply_txt; - QString m_cmd; -}; -} - -#endif // MAEMOTESTCONTROL_H diff --git a/libqsystemtest/manualverificationdlg.ui b/libqsystemtest/manualverificationdlg.ui deleted file mode 100644 index 77c7456..0000000 --- a/libqsystemtest/manualverificationdlg.ui +++ /dev/null @@ -1,111 +0,0 @@ -<ui version="4.0" > - <class>ManualVerificationDlg</class> - <widget class="QDialog" name="ManualVerificationDlg" > - <property name="geometry" > - <rect> - <x>0</x> - <y>0</y> - <width>720</width> - <height>540</height> - </rect> - </property> - <property name="windowTitle" > - <string>Manual Verification Step</string> - </property> - <layout class="QVBoxLayout" > - <item> - <widget class="QLabel" name="label" > - <property name="text" > - <string>Please follow the indicated steps and click Pass or Fail depending on the outcome. </string> - </property> - <property name="scaledContents" > - <bool>true</bool> - </property> - <property name="alignment" > - <set>Qt::AlignCenter</set> - </property> - <property name="wordWrap" > - <bool>true</bool> - </property> - </widget> - </item> - <item> - <widget class="QTextBrowser" name="test_steps" > - <property name="sizePolicy" > - <sizepolicy vsizetype="MinimumExpanding" hsizetype="Expanding" > - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="readOnly" > - <bool>true</bool> - </property> - </widget> - </item> - <item> - <layout class="QHBoxLayout" > - <item> - <widget class="QPushButton" name="abort_button" > - <property name="text" > - <string>Abort</string> - </property> - </widget> - </item> - <item> - <spacer> - <property name="orientation" > - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" > - <size> - <width>121</width> - <height>31</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QPushButton" name="okButton" > - <property name="text" > - <string>Pass</string> - </property> - </widget> - </item> - <item> - <widget class="QPushButton" name="cancelButton" > - <property name="text" > - <string>Fail</string> - </property> - </widget> - </item> - <item> - <widget class="QPushButton" name="learnButton" > - <property name="text" > - <string>Record</string> - </property> - </widget> - </item> - </layout> - </item> - </layout> - </widget> - <resources/> - <connections> - <connection> - <sender>okButton</sender> - <signal>clicked()</signal> - <receiver>ManualVerificationDlg</receiver> - <slot>accept()</slot> - <hints> - <hint type="sourcelabel" > - <x>403</x> - <y>406</y> - </hint> - <hint type="destinationlabel" > - <x>96</x> - <y>254</y> - </hint> - </hints> - </connection> - </connections> -</ui> diff --git a/libqsystemtest/meegotestcontrol.cpp b/libqsystemtest/meegotestcontrol.cpp deleted file mode 100644 index 2cfef89..0000000 --- a/libqsystemtest/meegotestcontrol.cpp +++ /dev/null @@ -1,31 +0,0 @@ -#include "meegotestcontrol.h" - -using namespace Qt4Test; - -MeeGoTestControl::MeeGoTestControl() - : TestControl() -{ - -} - -MeeGoTestControl::~MeeGoTestControl() -{ - -} - -bool MeeGoTestControl::deviceConfiguration( QString &reply ) -{ - return false; -} - -bool MeeGoTestControl::startApplication( const QString &application, const QStringList &arguments, - bool styleQtUITest, const QStringList &environment, QString &reply ) -{ - return false; -} - -bool MeeGoTestControl::killApplication( const QString &application, QString &reply ) -{ - return false; -} - diff --git a/libqsystemtest/meegotestcontrol.h b/libqsystemtest/meegotestcontrol.h deleted file mode 100644 index 6670899..0000000 --- a/libqsystemtest/meegotestcontrol.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef MEEGOTESTCONTROL_H -#define MEEGOTESTCONTROL_H - -#include "testcontrol.h" - -namespace Qt4Test { -class MeeGoTestControl : public TestControl -{ - Q_OBJECT -public: - MeeGoTestControl(); - virtual ~MeeGoTestControl(); - - bool deviceConfiguration( QString &reply ); - - bool startApplication( const QString &application, const QStringList &arguments, - bool styleQtUITest, const QStringList &environment, QString &reply ); - bool killApplication( const QString &application, QString &reply ); -}; -} - -#endif // MEEGOTESTCONTROL_H diff --git a/libqsystemtest/qabstracttest.cpp b/libqsystemtest/qabstracttest.cpp deleted file mode 100644 index 7b1a02a..0000000 --- a/libqsystemtest/qabstracttest.cpp +++ /dev/null @@ -1,743 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of QtUiTest. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <qabstracttest.h> -#include <QDir> -#include <QFileInfo> -#include <QMetaMethod> -#include <QThread> -#include <QTimer> - -#ifdef Q_OS_UNIX -# include <unistd.h> -# include <time.h> -# include <signal.h> -# include <setjmp.h> -#endif - -/*! - \enum QAbstractTest::LearnMode - - This enum specifies the learn mode setting. - - The learn mode affects the behavior of certain functions in QSystemTest, such as verifyImage(). - Additionally, a test may choose to use the current learn mode to determine how to handle - a test failure. - - \value LearnNone - Learn mode is off. Any mismatches encountered will cause a test failure. - \value LearnNew - The test should attempt to learn data which does not match existing test data. - \value LearnAll - The test should attempt to learn all data, even if it matches existing test data. - - \sa learnMode(), setLearnMode(), verifyImage() -*/ - -bool Autotest_QLog::m_enabled = false; - -QDebug Autotest_QLog::log(const char* category) -{ - QDebug r = QDebug(QtDebugMsg); - if ( category ) - r << category << ": "; - return r; -} - -class FatalTimeoutThread : public QThread -{ -Q_OBJECT -public: - FatalTimeoutThread(); - bool inEventLoop() const { return m_inEventLoop; } - void setTimeout(int timeout) { m_timeout = timeout; } - - void startTimer(); - void stopTimer(); - void stopThread(); - -protected: - void run(); - -private slots: - void enteredEventLoop(); - void _startTimer(); - void _stopTimer(); - void _stopThread(); - -private: - enum ExitCodes { TimedOut = 0, DidNotTimeOut, StartTimer, Exit }; - int m_timeout; - bool m_inEventLoop; -}; - -class QAbstractTestPrivate -{ -public: - QAbstractTest::LearnMode learnMode; - QString baseDataPath; - bool failEmptyTest; -}; - -static QString noslash(QString const &in) -{ - QString out(in); - while (out.endsWith("/")) out.chop(1); - return out; -} - -/* - \internal - \class QAbstractTest - \inpublicgroup QtUiTestExtension - \mainclass - \brief The QAbstractTest class is the base class for all QtUiTest System Tests. - - \ingroup qtuitest_unittest - \ingroup qtuitest_systemtest - \internal - - QAbstractTest provides some functionality helpful for all kinds of tests. - - In practice, a test class will almost always subclass QSystemTest. - - \sa QSystemTest, QtUiTest, QTestLib -*/ - -/* - \internal - Construct the test with the specified \a parent. -*/ -QAbstractTest::QAbstractTest(QString const &srcdir, QObject *parent) - : QTimedTest(parent) -{ - d = new QAbstractTestPrivate; - d->baseDataPath = noslash(QDir::homePath()) + "/.qtest"; - d->learnMode = LearnNone; - d->failEmptyTest = false; - if (!srcdir.isEmpty()) - setupTestDataPath(qPrintable(QString("%1/tst_phonytest.cpp").arg(srcdir))); -} - -/* - \internal -*/ -QAbstractTest::~QAbstractTest() -{ - delete d; -} - -/*! - Returns the current learn mode. -*/ -QAbstractTest::LearnMode QAbstractTest::learnMode() const -{ - return d->learnMode; -} - -/*! - Sets the current learn \a mode. -*/ -void QAbstractTest::setLearnMode(QAbstractTest::LearnMode mode) -{ - d->learnMode = mode; -} - -bool QAbstractTest::failEmptyTest() const -{ - return d->failEmptyTest; -} - -/*! - Returns the path in which data for the current test function will be saved to/retrieved from. - - The path follows the format \c baseDataPath/testCaseName/testFunctionName/dataTag, - where \c baseDataPath is the path returned by \l baseDataPath(). - - Internally, the current data path does not affect the behaviour of QAbstractTest. - However, subclasses may use the value returned by this function to decide where to - store learned data. - - \sa baseDataPath(), learnMode() -*/ -QString QAbstractTest::currentDataPath() const -{ - return d->baseDataPath + "/" + currentTestFunction() + "/" + currentDataTag(); -} - - -/*! - Returns the path which functions as the root directory to all the test data. - - This path defaults to the "testdata" subdirectory of the directory in which the source file of - the current test is located; if the source file no longer exists, the path defaults to - \c $HOME/.qtest/ . In either case, it can be overridden by the user with the \c -data command line switch. - - The base data path contains the test data for functions such as verifyImage(). - It can also be used within a test to use testdata stored in files. - - \sa currentDataPath(), learnMode() -*/ -QString QAbstractTest::baseDataPath() const -{ - return d->baseDataPath + "/"; -} - -/*! - Set the \a path which functions as the root directory to all of the test data. - - The base data path contains the test data for functions such as verifyImage(). - It can also be used within a test to use testdata stored in files. - - \sa baseDataPath() -*/ -void QAbstractTest::setBaseDataPath(QString const &path) -{ - d->baseDataPath = path; -} - -#ifdef TESTS_SHARED_DIR -/*! - Returns the path which functions as the shared directory available to tests. - - The shared data path contains scripts and other functions available to tests. This is the default search - location for the \c include feature. - -*/ -QString QAbstractTest::sharedDataPath() const -{ - return noslash(TESTS_SHARED_DIR); -} -#endif -/*! - Returns the current data tag, or an empty string if the test function has no test data associated - with it. The data tag is the string used to identify each row in the test data table. - - Example: - \code - walkTheDog: function(street) { - // At the moment, application crashes if we walk on concrete; this is - // a known failure - if (currentDataTag().startsWith("concrete sidewalk")) - expectFail("concrete is known to break"); - - enter( street, "Destination" ); - select( "Walk the Dog" ); - compare( getText("Status"), "Walked" ); - } - walkTheDog_data: { - "concrete sidewalk 1": [ "East St." ], - "concrete sidewalk 2": [ "West St." ], - grassy: [ "North St." ], - muddy: [ "South St." ] - } - \endcode -*/ -QString QAbstractTest::currentDataTag() const -{ - return QTest::currentDataTag(); -} - -/*! - Returns the name of the currently executing test case. - - \sa currentTestFunction() -*/ -QString QAbstractTest::testCaseName() const -{ - return metaObject()->className(); -} - -/*! - Returns the name of the testfunction that is currently being executed. - If \a fullName is true, the fully qualified name (including the test case name) will be returned. - - Example, in a file named sys_mytest: - \code - testYoyo: function() { - currentTestFunction(); // returns "testYoyo" - currentTestFunction(true); // returns "sys_mytest::testYoyo" - } - \endcode - - \sa testCaseName() -*/ -QString QAbstractTest::currentTestFunction( bool fullName ) const -{ - return fullName ? QString("%1::%2").arg(testCaseName()).arg(QTest::currentTestFunction()) : (QString(QTest::currentTestFunction())); -} - -#ifndef QTCREATOR_QTEST -/* - \internal - Executes all test functions as specified on the command line, while running the - application event loop. - - The \a argc and \a argv parameters should be passed in from the main() - function of the application and are used to parse command-line arguments - specific to QAbstractTest. Also, subclasses may override the runTest(), - - The \a filename parameter contains the full path to the source file containing the - test in question. It is used to determine where test data should be located. - -*/ -int QAbstractTest::exec( int argc, char* argv[], char* filename ) -{ - setupTestDataPath(filename); - - QStringList options; - for (int i = 1; i < argc; ++i) options << argv[i]; - - QString defOpt = qgetenv("QTUITEST_DEFAULT_OPTIONS"); - if (defOpt.length()) { - options << defOpt.split(' '); - } - - processCommandLine(options); - if (options.isEmpty()) { - qWarning("No script specified"); - exit(1); - } - - return runTest(options.first(), options, QStringList()); -} -#endif - -//#ifndef QTCREATOR_QTEST -/* - \internal - Print a usage message. - \a argc and \a argv are command-line arguments. - Any subclass which overrides processCommandLine() should also override this - function and provide documentation for their arguments. -*/ -void QAbstractTest::printUsage() const -{ - qWarning( - " Usage:\n" - " qtuitestrunner [file] [options] [testfunction[:datatag]]...\n" - "\n" - " 'file' is a QtScript file containing the testcase.\n" - " 'testfunctions' is a list of functions to execute (separated by spaces).\n" - " If no testfunctions are specified, ALL functions will be executed.\n" - "\n" - " basic test options:\n" - " -functions : Returns a list of current testfunctions\n" - " -xunitxml : Outputs results as XML XUnit document\n" - " -xml : Outputs results as XML document\n" - " -lightxml : Outputs results as stream of XML tags\n" - " -flush : Flushes the results (use with -xml or -lightxml)\n" - " -o filename : Writes all output into a file\n" - " -silent : Only outputs warnings and failures\n" - " -v : Print 'Autotest' log messages\n" - " -v1 : Also print enter messages for each testfunction\n" - " -v2 : Also print out each QVERIFY/QCOMPARE/QTEST\n" - " -vs : Print every signal emitted\n" - " -timed : Print time elapsed (in milliseconds) for each testfunction\n" - " -maxtime ms : Maximum time allowed per test, in milliseconds (implies -timed).\n" - " If this time is reached, a fatal error occurs and subsequent tests will not run.\n" - " -maxwarnings n : Sets the maximum amount of messages to output.\n" - " 0 means unlimited, default: 2000\n" - " -failempty : Test functions that test nothing will FAIL\n" - " -help : This help\n" - "\n" - " learn mode options:\n" - " -learn : All 'learnable' new and changed data may be added/updated.\n" - " -learn-all : All 'learnable' data may be added/updated, even if it has not changed.\n" - " -data d : The location of the testdata; this value is used for dynamic data loading (i.e. dynamic\n" - " data that can't be hardcoded in the testcase itself).\n" - " If -data is not specified the testcase will first look in the testdata subdirectory\n" - " of the directory containing the test source file, then in $HOME/.qtest\n" - ); -} -//#endif - -/* - \internal - Processes the command line parameters specified by \a argc, \a argv. - Subclasses may reimplement this function to handle specific arguments. -*/ -void QAbstractTest::processCommandLine( QStringList &args ) -{ - QMutableStringListIterator it(args); - - while (it.hasNext()) { - QString arg = it.next(); - if ( !arg.compare("-data", Qt::CaseInsensitive) ) { - it.remove(); - if (!it.hasNext()) qFatal("Expected a value after %s", qPrintable(arg)); - setBaseDataPath(it.next()); - it.remove(); - } else if ( !arg.compare("-v", Qt::CaseInsensitive) ) { - it.remove(); - Autotest_QLog::m_enabled = true; - } else if ( !arg.compare("-v1", Qt::CaseInsensitive) || - !arg.compare("-v2", Qt::CaseInsensitive) ) { - // Don't consume -v1 or -v2 - Autotest_QLog::m_enabled = true; - } else if ( !arg.compare("-learn", Qt::CaseInsensitive) ) { - it.remove(); - setLearnMode(LearnNew); - } else if ( !arg.compare("-learn-all", Qt::CaseInsensitive) ) { - it.remove(); - setLearnMode(LearnAll); - } else if ( !arg.compare("-failempty", Qt::CaseInsensitive) ) { - it.remove(); - d->failEmptyTest = true; - } else if ( !arg.compare("-timed", Qt::CaseInsensitive) ) { - it.remove(); - QTimedTest::pass_through = false; - QTimedTest::print_times = true; - } else if ( !arg.compare("-maxtime", Qt::CaseInsensitive) ) { - it.remove(); - if (!it.hasNext()) qFatal("Expected a value after %s", qPrintable(arg)); - QTimedTest::pass_through = false; - bool ok; - timeout_thread = new FatalTimeoutThread; - timeout_thread->setTimeout(it.next().toInt(&ok)); - if (!ok) qFatal("Invalid parameter to -maxtime"); - it.remove(); - } else if ( !arg.compare("-help", Qt::CaseInsensitive) || - !arg.compare("--help", Qt::CaseInsensitive) || - !arg.compare("-h", Qt::CaseInsensitive) ) { - it.remove(); -#ifndef QTCREATOR_QTEST - printUsage(); - exit(0); -#endif - } - } -} - -#if defined(Q_OS_UNIX) && !defined(Q_OS_SYMBIAN) -jmp_buf segfault_jmp; - -void handle_segfault(int signum) -{ - signal(signum, SIG_DFL); - QTest::qFail("A segmentation fault occurred.", "Unknown file", 0); - longjmp(segfault_jmp, 1); - _exit(0); -} -#endif - -//# ifndef QTCREATOR_QTEST -/* - \internal - Run test with arguments \a argc, \a argv, and return an exit code. - The base implementation executes private slots as testfunctions - using QTest::qExec(). Subclasses may reimplement this function to provide - other behaviour. -*/ -int QAbstractTest::runTest(const QString &fname, const QStringList &args, - const QStringList &environment) -{ - Q_UNUSED(fname); - Q_UNUSED(environment); -#if defined(Q_OS_UNIX) && !defined(Q_OS_SYMBIAN) - signal(SIGSEGV, handle_segfault); - if (!setjmp(segfault_jmp)) -#endif - return QTest::qExec( this, args ); - return -1; -} -//#endif - -/*! - \internal - Set up the test data path, where \a filename is the name of the test source file. -*/ -void QAbstractTest::setupTestDataPath(const char *filename) -{ - d->baseDataPath = noslash(QDir::homePath()) + "/.qtest/" + testCaseName(); - - if (filename) { - // If we are given a filename, try to use it as test path - QFileInfo sourceFile( filename ); - QString sfPath = sourceFile.canonicalPath(); - QString dirPath = sourceFile.dir().canonicalPath(); - QString path = sfPath.isEmpty() ? dirPath : sfPath; - if (!path.isEmpty()) { - d->baseDataPath = noslash(path) + "/testdata"; - } - } - - // Try to ensure the data directory exists - QDir dir; - dir.mkpath(d->baseDataPath); -} - -class Timer -{ -public: - virtual ~Timer() {} - virtual void start() = 0; - virtual int elapsed() const = 0; -}; - -class RealTimeTimer : public Timer -{ -public: - void start() { t.start(); } - int elapsed() const { return t.elapsed(); } -private: - QTime t; -}; - -#if defined(Q_OS_UNIX) && !defined(Q_OS_SYMBIAN) -class ProcessorTimeTimer : public Timer -{ -public: - void start() { s = clock(); } - int elapsed() const { return (int)(((double)(clock() - s))/((double)CLOCKS_PER_SEC)*1000.0); } -private: - clock_t s; -}; -#endif - - -QTimedTest::QTimedTest(QObject *parent) - : QObject(parent), pass_through(true), print_times(false), - timeout_thread(0), realTimer(0), cpuTimer(0) -{} - -QTimedTest::~QTimedTest() -{ - if (timeout_thread) { - timeout_thread->stopThread(); - timeout_thread->wait(); - delete timeout_thread; - } - delete realTimer; - delete cpuTimer; -} - -static bool isTimeableSlot(const QMetaMethod &sl) -{ - if (sl.access() != QMetaMethod::Private || !sl.parameterTypes().isEmpty() - || qstrlen(sl.typeName()) || sl.methodType() != QMetaMethod::Slot) - return false; - const char *sig = sl.signature(); - int len = qstrlen(sig); - if (len < 2) - return false; - if (sig[len - 2] != '(' || sig[len - 1] != ')') - return false; - if (len > 7 && strcmp(sig + (len - 7), "_data()") == 0) - return false; -/* - It makes sense to time init() etc also. - if (strcmp(sig, "initTestCase()") == 0 || strcmp(sig, "cleanupTestCase()") == 0 - || strcmp(sig, "cleanup()") == 0 || strcmp(sig, "init()") == 0) - return false; -*/ - - return true; -} - -FatalTimeoutThread::FatalTimeoutThread() : QThread() -{ - m_timeout = 0; - m_inEventLoop = false; -} - -void FatalTimeoutThread::enteredEventLoop() -{ - m_inEventLoop = true; -} - -void FatalTimeoutThread::startTimer() -{ - QMetaObject::invokeMethod(this, "_startTimer"); -} - -void FatalTimeoutThread::stopTimer() -{ - QMetaObject::invokeMethod(this, "_stopTimer"); -} - -void FatalTimeoutThread::stopThread() -{ - QMetaObject::invokeMethod(this, "_stopThread"); -} - -void FatalTimeoutThread::_startTimer() -{ - exit(StartTimer); -} - -void FatalTimeoutThread::_stopTimer() -{ - exit(DidNotTimeOut); -} - -void FatalTimeoutThread::_stopThread() -{ - exit(Exit); -} - -void FatalTimeoutThread::run() -{ - QTimer t; - connect(&t, SIGNAL(timeout()), this, SLOT(quit())); - QTimer::singleShot(0, this, SLOT(enteredEventLoop())); - - int code; - do { - code = exec(); - switch (code) { - case TimedOut: - QTest::qFail(qPrintable(QString("Test did not finish within the allowed %1 ms").arg(m_timeout)), "Unknown file", 0); -#if defined(Q_OS_UNIX) && !defined(Q_OS_SYMBIAN) - longjmp(segfault_jmp, 1); -#endif - _exit(0); - case DidNotTimeOut: - t.stop(); - break; - case StartTimer: - t.setInterval(m_timeout); - t.start(); - break; - default: break; - } - } while(code != Exit); -} - -int QTimedTest::qt_metacall(QMetaObject::Call _c, int _id, void **_a) -{ - if (!realTimer) { - have_init = isTimeableSlot(metaObject()->method(metaObject()->indexOfMethod("init()"))); - have_cleanup = isTimeableSlot(metaObject()->method(metaObject()->indexOfMethod("cleanup()"))); - realTimer = new RealTimeTimer; -#if defined(Q_OS_UNIX) && !defined(Q_OS_SYMBIAN) - cpuTimer = new ProcessorTimeTimer; -#endif - } - - if (pass_through) - return real_qt_metacall(_c, _id, _a); - - bool timed = isTimeableSlot(metaObject()->method(_id)); - bool is_init = (_id == metaObject()->indexOfMethod("init()")); - bool is_cleanup = (_id == metaObject()->indexOfMethod("cleanup()")); - bool is_single = (_id == metaObject()->indexOfMethod("initTestCase()") || - _id == metaObject()->indexOfMethod("cleanupTestCase()")); - - bool should_start_timer = timed && (is_single || is_init || (!have_init && !is_cleanup)); - bool should_stop_timer = timed && (is_single || (!is_init && (!have_cleanup || is_cleanup))); - - if (should_start_timer) { - if (timeout_thread) { - if (timeout_thread != timeout_thread->thread()) { - timeout_thread->moveToThread(timeout_thread); - timeout_thread->start(); - while (!timeout_thread->inEventLoop()) { - timeout_thread->wait(50); - } - } - timeout_thread->startTimer(); - } - realTimer->start(); - if (cpuTimer) cpuTimer->start(); - } - - pass_through = true; - int ret = this->qt_metacall(_c, _id, _a); - pass_through = false; - - if (should_stop_timer) { - if (print_times) QDebug(QtDebugMsg) << - qPrintable( - QString("Test time: %1 ms CPU, %2 ms real") - .arg(cpuTimer ? cpuTimer->elapsed() : -1) - .arg(realTimer->elapsed()) - ); - if (timeout_thread) timeout_thread->stopTimer(); - } - - return ret; -} - -static const uint qt_meta_data_QTimedTest[] = { - - // content: - 1, // revision - 0, // classname - 0, 0, // classinfo - 0, 0, // methods - 0, 0, // properties - 0, 0, // enums/sets - - 0 // eod -}; - -static const char qt_meta_stringdata_QTimedTest[] = { - "QTimedTest\0" -}; - -const QMetaObject QTimedTest::staticMetaObject = { - { &QObject::staticMetaObject, qt_meta_stringdata_QTimedTest, - qt_meta_data_QTimedTest, 0 } -}; - -const QMetaObject *QTimedTest::metaObject() const -{ - return &staticMetaObject; -} - -void *QTimedTest::qt_metacast(const char *_clname) -{ - if (!_clname) return 0; - if (!strcmp(_clname, qt_meta_stringdata_QTimedTest)) - return static_cast<void*>(const_cast< QTimedTest*>(this)); - return QObject::qt_metacast(_clname); -} - -int QTimedTest::real_qt_metacall(QMetaObject::Call _c, int _id, void **_a) -{ - _id = QObject::qt_metacall(_c, _id, _a); - if (_id < 0) - return _id; - return _id; -} - -#include "qabstracttest.moc" diff --git a/libqsystemtest/qabstracttest.h b/libqsystemtest/qabstracttest.h deleted file mode 100644 index 2a20d09..0000000 --- a/libqsystemtest/qabstracttest.h +++ /dev/null @@ -1,148 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of QtUiTest. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QABSTRACTTEST_H -#define QABSTRACTTEST_H - -#if ! defined Q_QDOC - -#include <QObject> -#include <QTest> -#include "qtuitestglobal.h" -#include <qdebug.h> - -class QSYSTEMTEST_EXPORT Autotest_QLog { -public: - static inline bool enabled() { return m_enabled; } - static QDebug log(const char* category); -private: - static bool m_enabled; - friend class QAbstractTest; -}; - -class QAbstractTestPrivate; -class FatalTimeoutThread; -class Timer; - -class QSYSTEMTEST_EXPORT QTimedTest : public QObject -{ -#ifndef Q_MOC_RUN - Q_OBJECT -#endif -public: - QTimedTest(QObject *parent=0); - virtual ~QTimedTest(); - - int real_qt_metacall(QMetaObject::Call, int, void **); - -protected: - bool pass_through; - bool print_times; - bool have_init; - bool have_cleanup; - FatalTimeoutThread *timeout_thread; - Timer *realTimer; - Timer *cpuTimer; -}; - -#ifdef Q_QDOC -namespace QAbstractTest -#else -class QSYSTEMTEST_EXPORT QAbstractTest : public QTimedTest -#endif -{ - Q_OBJECT - -public: - enum LearnMode - { - LearnNone, - LearnNew, - LearnAll - }; - -#ifndef Q_QDOC - QAbstractTest(QString const &srcdir = -#ifdef QTUITEST_SRCDIR - QTUITEST_SRCDIR -#else - QString() -#endif - , QObject *parent = 0); - virtual ~QAbstractTest(); - -# ifndef QTCREATOR_QTEST - int exec( int argc, char* argv[], char* filename = 0 ); -# endif -#endif - -public slots: - LearnMode learnMode() const; - void setLearnMode(LearnMode mode); - bool failEmptyTest() const; - - QString currentDataPath() const; - QString baseDataPath() const; - void setBaseDataPath(QString const &path); -#ifdef TESTS_SHARED_DIR - QString sharedDataPath() const; -#endif - QString currentDataTag() const; - virtual QString testCaseName() const; - QString currentTestFunction( bool fullName = false ) const; - -#ifndef Q_QDOC -protected: - virtual int runTest(const QString &fname, const QStringList ¶meters, - const QStringList &environment); - virtual void printUsage() const; - virtual void processCommandLine(QStringList&); - - virtual void setupTestDataPath(const char *filename); -#endif - -private: - QAbstractTestPrivate *d; -}; - -#endif - -#endif diff --git a/libqsystemtest/qsystemtest.cpp b/libqsystemtest/qsystemtest.cpp deleted file mode 100644 index f41157d..0000000 --- a/libqsystemtest/qsystemtest.cpp +++ /dev/null @@ -1,3578 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of QtUiTest. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <qsystemtest.h> -#include "qsystemtestmaster_p.h" -#include "qtuitest_config.h" -#include "qtestide.h" -#include "ui_recorddlg.h" - -#ifdef QTCREATOR_QTEST -# include "testoutputwindow.h" -#endif - -#include <QDir> -#include <QProcess> -#include <QMessageBox> -#include <QTemporaryFile> -#include <QTextEdit> -#include <QSignalSpy> -#include <QSettings> - -#include <sys/types.h> -#include <signal.h> -#include <errno.h> - -#undef qLog -#define qLog(A) if (0); else (QDebug(QtDebugMsg) << #A ":") -#define OBJECT_EXIST_TIMEOUT 1000 - -#define BT(message) (\ - message["location"] = QString("%1:%2%3").arg(__FILE__).arg(__LINE__).arg(!message["location"].toString().isEmpty() ? QString("\n") + message["location"].toString() : QString()),\ - message) - -#undef QFAIL -#define QFAIL(message) \ -do {\ - setQueryError(message);\ - return;\ -} while(0) - -#define CHECK_FORCED_MANUAL(msg) \ -if (m_run_as_manual_test) {\ - m_manual_commands += msg.event() + msg.msgId() + msg.toString() + "\n";\ - QTestMessage reply;\ - reply["status"] = "OK";\ - return reply;\ -} - -QString quote(const QString &item) -{ - if (item == "MAGIC_DATA" || item.contains("'")) - return item; - else - return "'" + item + "'"; -} - -QString mouseButtons( QFlags<Qt::MouseButton> buttons ) -{ - QString ret; - if (buttons) { - ret = ""; - if ((buttons & Qt::LeftButton) > 0) - ret += "'Left'+ "; - if ((buttons & Qt::MidButton) > 0) - ret += "'Mid'+ "; - if ((buttons & Qt::RightButton) > 0) - ret += "'Right'+ "; - if ((buttons & Qt::XButton1) > 0) - ret += "'X1'+ "; - if ((buttons & Qt::XButton2) > 0) - ret += "'X2'+ "; - ret = ret.left(ret.length()-2); - } - return ret; -} - -/*! - \enum QSystemTest::EnterMode - - This enum specifies whether enter() should commit the entered value (eg, by simulating a Select - keypress) or not. - - \value Commit Commit the value (default). - \value NoCommit Do not commit the value. -*/ - -/*! - \enum QSystemTest::StartApplicationFlag - - This enum describes additional behaviour to use when starting applications - by startApplication(). - - \value NoFlag Don't apply any of the below flags. - \value WaitForFocus Wait for the application to gain keyboard focus before returning. - \value BackgroundCurrentApplication Use multitasking to background the current application. - The default behaviour is to exit the current application. -*/ - -/*! - \enum QSystemTest::SkipMode - - This enum describes the modes for skipping tests during execution of the test data. - \value SkipSingle Skip the rest of this test function for the current test data entry, but continue execution of the remaining test data. - \value SkipAll Skip the rest of this test function, and do not process any further test data for this test function. - - \sa skip(), QTest::SkipMode -*/ - -/*! - \enum QSystemTest::LabelOrientation - - This enum is used to indicate the expected position of a label relative to the widget it is - associated with. Use setLabelOrientation() to change the expected layout. - - \value LabelLeft Label is located to left of widget. - \value LabelRight Label is located to right of widget. - \value LabelAbove Label is located above widget. - \value LabelBelow Label is located below widget. - - \sa labelOrientation(), setLabelOrientation() -*/ - -/*! - \preliminary - \namespace QSystemTest - \brief The QSystemTest namespace provides script based system test functionality for Qt. - - \ingroup qtuitest_systemtest - \inpublicgroup QtUiTestModule - - This documentation describes the API reference for the QtUiTest scripting language. Please read the \l{QtUiTest Manual} for a full description of the system test tool. - -*/ - -/*! \internal */ -QMap<QString, int> QSystemTest::filteredMessages() const -{ - return m_filteredMessages; -} - -/*! \internal */ -void QSystemTest::clearFilteredMessages() -{ - m_filteredMessages.clear(); -} - -/*! \internal */ -bool QSystemTest::shouldFilterMessage(char const *msg) -{ - static QList<QRegExp> filters; - if (filters.isEmpty()) { - QStringList defaultFilters; -// defaultFilters -// << "^Connected to VFB server" -// << "^QTimeLine::start: already running$" // Bug -// ; - QStringList stringFilters = QSettings("Trolltech", "QtUitest") - .value("Logging/Filters", defaultFilters) - .toStringList(); - foreach (QString s, stringFilters) { - filters << QRegExp(s); - } - } - - QString message = QString::fromLocal8Bit(msg); - foreach (QRegExp r, filters) { - if (-1 != r.indexIn(message)) { - ++m_filteredMessages[message]; - return true; - } - } - return false; -} - -/*! - \internal - Creates the test class. - Generally you would use the \l {QTest}{QTEST_MAIN()} macro rather than create the class directly. -*/ -QSystemTest::QSystemTest() - : QAbstractTest() - , event_timer(0) - , m_test_app(0) - , m_recorded_events_edit(0) - , recorded_events_as_code(true) - , record_prompt(false) - , query_warning_mode(true) - , fatal_timeouts(1) - , timeouts(0) - , m_keyclickhold_key((Qt::Key)0) - , current_application("") - , current_app_version("") - , m_loc_fname("") - , m_loc_line(-1) - , m_auto_mode(false) - , m_run_as_manual_test(false) - , m_aut_port(DEFAULT_AUT_PORT) - , m_keep_aut(false) - , m_silent_aut(false) - , m_no_aut(false) - , m_demo_mode(false) - , m_verbose(false) - , m_strict_mode(false) - , m_visible_response_time(4000) - , recorded_events() - , m_recorded_code() - , display_id(0) - , device() - , m_mousePreferred(false) - , screenGeometry() - , theme() - , m_config_id() - , m_recording_events(false) - , m_expect_app_close(false) -{ - m_env.clear(); - ssh_param.host = DEFAULT_AUT_HOST; - ssh_param.port = DEFAULT_AUTSSH_PORT; - device_controller = 0; - - QTestIDE::instance()->setSystemTest(this); - (void)qMetaTypeId<RecordEvent>(); - (void)qMetaTypeId< QList<RecordEvent> >(); - qRegisterMetaType<QTestMessage>("QTestMessage"); - qRegisterMetaType<QTestMessage*>("QTestMessage*"); -} - -/*! - \internal - Destroys the test class. -*/ -QSystemTest::~QSystemTest() -{ - if (device_controller) - device_controller->killApplications(); - - delete device_controller; - delete event_timer; - delete m_test_app; - while (expected_msg_boxes.count() > 0) - delete expected_msg_boxes.takeFirst(); -} - -void QSystemTest::setConnectionParameters( Qt4Test::TestController::TestDeviceType &type, - Core::SshConnectionParameters param ) -{ - ssh_param = param; - device_controller = new Qt4Test::TestController( type, ¶m); -} - -/*! - Returns the signature of the currently active window. - - \sa {Query Paths} -*/ -QString QSystemTest::activeWindow() -{ - if (runAsManualTest()) { - manualTestData( "the currently active window" ); - return "MAGIC_DATA"; - } - - QString ret; - return queryWithReturn(ret, "activeWindow", ""); -} - -/*! - Returns the signature of the widget that has keyboard focus. - - Example: - \code - // Get the currently focused widget in the current app - print( focusWidget() ); - \endcode - - \sa {Query Paths} -*/ -QString QSystemTest::focusWidget() -{ - if (runAsManualTest()) { - manualTestData( "the currently focused widget" ); - return "MAGIC_DATA"; - } - - QString ret; - return queryWithReturn(ret, "focusWidget", ""); -} - - -/*! - Returns the currently selected text from the widget specified by \a {queryPath}. - If no text is selected, returns all text. - For list-type widgets, returns the text for the currently selected item. - - Example: - \code - // Enter text in two fields, then go back to the first - // and make sure it still has the right text - enter("Australia", "Home"); - enter("dog walker", "Occupation"); - compare( getSelectedText("Home"), "Australia" ); - \endcode - - \sa {Query Paths}, {Querying Objects} -*/ -QString QSystemTest::getSelectedText( const QString &queryPath ) -{ - if (runAsManualTest()) { - manualTestData( "selected text for " + quote(queryPath) ); - return "MAGIC_DATA"; - } - - QString ret = ""; - return queryWithReturn(ret, "getSelectedText", queryPath); -} - -/*! - Returns all text from the widget specified by \a {queryPath}, or the current - focus widget if \a {queryPath} is not specified. - For list-type widgets, returns the text for all items separated by newlines. - - Example: - \code - // Get current content of "address" field - print( getText("Address") ); - \endcode - - \sa {Query Paths}, {Querying Objects} -*/ -QString QSystemTest::getText( const QString &queryPath ) -{ - if (runAsManualTest()) { - manualTestData( "text for " + quote(queryPath) ); - return "MAGIC_DATA"; - } - - QString ret; - return queryWithReturn(ret, "getText", queryPath); -} - -/*! - Returns the currently selected value from the widget specified by \a {queryPath}. - If no value is selected, returns all data in a single value. - For list-type widgets, returns the currently selected value. - - \sa getSelectedText(), {Query Paths}, {Querying Objects} -*/ -QVariant QSystemTest::getSelectedValue( const QString &queryPath ) -{ - QVariant ret; - if (runAsManualTest()) { - manualTestData( "selected value for " + quote(queryPath) ); - ret = "MAGIC_DATA"; - return ret; - } - - QString msg("getSelectedValue"); - QTestMessage reply; - QTestMessage testMessage(msg); - if (!doQuery(testMessage, queryPath, &reply)) return ret; - if (!reply[msg].isValid()) { - reply["status"] = QString("ERROR: no data in reply to %1; status: %2").arg(msg).arg(reply["status"].toString()); - setQueryError(reply); - return ret; - } - return reply[msg]; -} - -/*! - Returns the value from the widget specified by \a {queryPath}. - For list-type widgets, returns a list containing all values. - - \sa getText(), {Query Paths}, {Querying Objects} -*/ -QVariant QSystemTest::getValue( const QString &queryPath ) -{ - QVariant ret; - if (runAsManualTest()) { - manualTestData( "value for " + quote(queryPath) ); - ret = "MAGIC_DATA"; - return ret; - } - - QString msg("getValue"); - QTestMessage reply; - QTestMessage testMessage(msg); - if (!doQuery(testMessage, queryPath, &reply)) return ret; - if (!reply[msg].isValid()) { - reply["status"] = QString("ERROR: no data in reply to %1; status: %2").arg(msg).arg(reply["status"].toString()); - setQueryError(reply); - return ret; - } - return reply[msg]; -} - -/*! - Returns true if the primary input method is mouse/touchscreen. - - \sa setMousePreferred() -*/ -bool QSystemTest::mousePreferred() -{ - if (runAsManualTest()) { - qDebug() << "QSystemTest::mousePreferred() set to 'true'"; - return true; //FIXME TODO - } - - bool ret; - return queryWithReturn(ret, "mousePreferred", ""); -} - -/*! - If \a useMouse is true, indicates that QtUiTest should use mouse/touchscreen - events to select items on the screen. If false, the keyboard will be used. - - The setting will remain active until the application under test closes, or - until the value is changed by another call to setMousePreferred(). - - \sa mousePreferred() -*/ -void QSystemTest::setMousePreferred(bool useMouse) -{ - QTestMessage message("setMousePreferred"); - message["useMouse"] = useMouse; - queryPassed( "OK", "", BT(message)); -} - -/*! - Returns the label orientation, used by QtUiTest to assign labels to - widgets. - - \sa setLabelOrientation() -*/ -QSystemTest::LabelOrientation QSystemTest::labelOrientation() -{ - if (runAsManualTest()) { - qDebug() << "QSystemTest::labelOrientation() set to 'LabelLeft'"; - return LabelLeft; //FIXME TODO - } - - int ret; - return static_cast<LabelOrientation>(queryWithReturn(ret, "labelOrientation", "")); -} - -/*! - Set the expected label orientation to \a orientation. This value is used by - QtUiTest to work out which labels refer to which widgets. By default, this - value is LabelLeft (on left-to-right locales) or LabelRight (on right-to-left - locales). - - The setting will remain active until the application under test closes, or - until the value is changed by another call to setLabelOrientation(). - - \sa labelOrientation() -*/ -void QSystemTest::setLabelOrientation(LabelOrientation orientation) -{ - QTestMessage message("setLabelOrientation"); - message["orientation"] = orientation; - queryPassed( "OK", "", BT(message)); -} - -/*! - Returns a list of all items from the list-type widget specified by \a {queryPath}. - - The items will be returned in the order they are stored in the widget (for example, - for a simple list view the items will be returned from top to bottom). - - Example: - \code - // Verify that "gender" combobox contains male and female only - var g = getList("Gender"); - compare( g.length == 2 ); - verify( g.contains("Male") ); - verify( g.contains("Female") ); - \endcode - - \sa {Query Paths}, {Querying Objects} -*/ -QStringList QSystemTest::getList( const QString &queryPath ) -{ - if (runAsManualTest()) { - manualTestData( "the contents of list " + quote(queryPath) ); - return QStringList("MAGIC_DATA"); - } - - QStringList ret; - return queryWithReturn(ret, "getList", queryPath); -} - -QPoint QSystemTest::getCenter( const QString &item, const QString &queryPath ) -{ - if (item.isNull()) return QPoint(); - - if (runAsManualTest()) { - manualTestData( "the center of " + quote(item) ); - return QPoint(); - } - - QTestMessage message("getCenter"); - message["item"] = item; - queryPassed("OK", "", BT(message), queryPath); - QTestMessage reply; - if (!queryPassed( "OK", "", BT(message), queryPath, &reply )) return QPoint(); - if (!reply["getCenter"].isValid()) { - fail("Failed to get center for item"); - return QPoint(); - } - return reply["getCenter"].value<QPoint>(); -} -/*! - Returns a list of all the labels that are visible in the current active window or the widget specified by \a {queryPath}. - A label is usually a non-editable widget (such as a QLabel) that is associated with an editable field. The label is used to - give the user a visual clue of the meaning of the editable field. Labels are used by the user, and by QtUitest, to - navigate to fields. - - The items will be returned in the order they are displayed, i.e. from top left to bottom right. - - Example: - \code - // Verify that the current dialogs contains Labels named 'Name' and 'Email' - var g = getLabels(); - verify( g.length == 2 ); - verify( g.contains("Name") ); - verify( g.contains("Email") ); - \endcode - - \sa {Query Paths}, {Querying Objects} -*/ -QStringList QSystemTest::getLabels( const QString &queryPath ) -{ - QStringList ret; - if (runAsManualTest()) { - manualTestData( "all labels for " + quote(queryPath) ); - ret = QStringList() << "MAGIC_DATA"; - return ret; - } - - return queryWithReturn(ret, "getLabels", queryPath); -} - -/*! - Returns text stored in the clipboard, or an empty string if the clipboard does not contain any text. - - \sa setClipboardText() -*/ -QString QSystemTest::getClipboardText( ) -{ - if (runAsManualTest()) { - manualTestData( "the current clipboard text" ); - return "MAGIC_DATA"; - } - QString ret; - return queryWithReturn(ret, "getClipboardText", ""); -} - -/*! - Copies \a {text} into the clipboard. - - \sa getClipboardText() -*/ -void QSystemTest::setClipboardText( const QString& text ) -{ - if (runAsManualTest()) { - manualTest( "save " + quote(text) + " to the clipboard" ); - return; - } - - QTestMessage message("setClipboardText"); - message["text"] = text; - queryPassed( "OK", "", BT(message)); -} - -/*! - Returns the current window title for the application specified by \a {queryPath}. - If \a queryPath contains a widget component, it will be ignored. - - Example: - \code - startApplication("Contacts") ); - - ... - - // Make sure we are still in contacts - compare( currentTitle(), "Contacts" ); - \endcode - - \sa {Query Paths} -*/ -QString QSystemTest::currentTitle( const QString &queryPath ) -{ - if (runAsManualTest()) { - if (queryPath.isEmpty()) - manualTestData( "the current title" ); - else - manualTestData( "the current title for " + quote(queryPath) ); - return "MAGIC_DATA"; - } - - QString ret; - return queryWithReturn(ret, "currentTitle", queryPath); -} - -/*! - Returns the window titles for all top level windows in the application. -*/ -QStringList QSystemTest::getWindowTitles() -{ - if (runAsManualTest()) { - manualTestData( "all window titles" ); - return QStringList("MAGIC_DATA"); - } - - QStringList ret; - return queryWithReturn(ret, "getWindowTitles", ""); -} - -/*! - Brings the window specified by \a titleOrSignature to the foreground. -*/ -void QSystemTest::activateWindow( const QString &titleOrSignature ) -{ - if (runAsManualTest()) { - manualTest( "activate window " + quote(titleOrSignature) ); - return; - } - - QTestMessage message("activateWindow"); - message["window"] = titleOrSignature; - queryPassed( "OK", "", BT(message)); -} - -/*! - Returns the name of the application which currently has keyboard focus. - The name will be the name returned by QCoreApplication::applicationName(), - which may be an empty string. - - Example: - \code - compare( currentApplication(), "addressbook" ); - \endcode - - \sa applicationVersion() -*/ -QString QSystemTest::currentApplication() -{ - return m_test_app->appName(); -} - -/*! - Returns the version of the application under test. This is the value - returned by QCoreApplication::applicationVersion(), which may be an - empty string. - - \sa applicationName() -*/ -QString QSystemTest::applicationVersion() -{ - return m_test_app->appVersion(); -} - -/*! - Returns the version of Qt used by the application under test. - - \sa applicationName() -*/ -QString QSystemTest::qtVersion() -{ - return m_test_app->qtVersion(); -} - -/*! - \internal - Returns the value of the environment variable for \a key set on the test - system. -*/ -QString QSystemTest::getenv(QString const& key) -{ - if (runAsManualTest()) { - manualTestData( "environment variable " + quote(key) ); - return "MAGIC_DATA"; - } - - QTestMessage message("getenv"); - message["key"] = key; - - QTestMessage reply; - if (!queryPassed( "OK", "", BT(message), "", &reply )) return QString(); - if (!reply["getenv"].isValid()) { - fail("No data in reply to getenv"); - return QString(); - } - return reply["getenv"].toString(); -} - -/*! - Returns true if the test system is running the operating system specified by \a os. - - The supported values are: UNIX, LINUX, MAEMO, MAC, WIN32, WINCE and SYMBIAN. -*/ -bool QSystemTest::checkOS(QString const& os) -{ - if (runAsManualTest()) { - manualTestData( "Operating System equals " + quote(os) ); - return true; - } - - QTestMessage message("checkOS"); - message["os"] = os; - - QTestMessage reply; - if (!queryPassed( "OK", "", BT(message), "", &reply )) return false; - if (!reply["checkOS"].isValid()) { - fail("Failed to get details of OS"); - return false; - } - return reply["checkOS"].toBool(); -} - -/*! - Returns the target identifier is used when needing to uniquely identifying - the target. - Default value for target identifier is \bold default unless set changed by - \list - \o the -targetID option to qtuitestrunner - \o the value of $QTUITEST_TARGETID environment variable when qtuitestrunner is launched - \o the value set using the function setTargetIdentifier() in the test script - \endlist - - /sa setTargetIdentifier() - */ -QString QSystemTest::targetIdentifier() -{ - if (m_run_as_manual_test) - return QString(); - - QTestMessage message("targetIdentifier"); - - QTestMessage reply; - if (!queryPassed( "OK", "", BT(message), "", &reply )) return QString(); - if (!reply["targetIdentifier"].isValid()) { - fail("No data in reply to targetIdentifier"); - return QString(); - } - return reply["targetIdentifier"].toString(); -} - -/*! - Sets the target identifier is used when needing to uniquely identifying - the target. - - /sa targetIdentifier() - */ -void QSystemTest::setTargetIdentifier(const QString &id) -{ - if (m_run_as_manual_test) - return; - - QTestMessage reply; - QTestMessage message("setTargetIdentifier"); - message["targetIdentifier"] = id; - - queryPassed( "OK", "", BT(message), "", &reply); -} - -/*! - \internal - Grabs a snapshot of the widget specified by \a {queryPath}, optionally excluding \a maskedWidgets from the snapshot. Each masked widget is replaced by a black rectangle, and any overlapping widgets will also be concealed. - - To get a snapshot of the entire application window, use the query path "". - - Example: - \code - // Get current screenshot and save to disk - QImage img = grabImage(""); - verify( img.save(currentDataPath() + "/snapshot.png", "PNG") ); - \endcode - - \sa {Query Paths}, verifyImage(), saveScreen() -*/ -QImage QSystemTest::grabImage(const QString &queryPath, const QStringList &maskedWidgets ) -{ - if (runAsManualTest()) { - // FIXME TODO - qDebug() << "QSystemTest::grabImage() skipped"; - return QImage(); - } - - QImage im; - - QTestMessage message("grabPixmap"); - message["mask"] = maskedWidgets; - - QTestMessage reply = query( BT(message), queryPath ); - if (reply["status"] != "OK" || queryFailed()) { - fail( "Couldn't grab image: " + reply.toString()); - } else { - if (!reply["grabPixmap"].isValid()) { - fail( "Test slave returned no image" ); - } else { - im = reply["grabPixmap"].value<QImage>(); - } - } - - return im; -} - -/*! - Grabs a snapshot of the widget specified by \a {queryPath}, and compares it against the reference snapshot \a expectedName. - - New snapshots are gathered by running the test in \l {Learn Mode}{learn mode}, and are stored in the \c testdata subdirectory of the directory containing the test script. When learn mode is used, a failed image comparison will result in a tester being presented with a manual verification dialog. - - If there is a mismatch between the images, the current test fails. - - When in learn mode, if \a comment is provided it will be shown to the user to help in determining whether or not the pixmap should be accepted. - - \a maskedWidgets is a list of query paths specifying widgets to be excluded from the snapshot. This allows constantly changing widgets to be hidden from view while the snapshot is taken. Each masked widget is replaced by a black rectangle, and any overlapping widgets will also be concealed. - - Example: - \code - verifyImage( "task_completed", "", "Verify that the current task is shown with a green tick indicating completion" ); - \endcode - - \sa saveScreen() -*/ -void QSystemTest::verifyImage( const QString &expectedName, const QString &queryPath, const QString &comment, const QStringList &maskedWidgets ) -{ - if (runAsManualTest()) { - if (!comment.isEmpty()) - manualTest( comment ); - else - manualTest( "verify that " + quote(queryPath) + " looks as expected" ); - return; - } - - // Determine the filename - // If the function was passed an explicit filename (indicated by an extension) it will be used directly - // otherwise system specific values are prepended to the name. - QString expectedFilename = currentDataPath(); - if ( expectedName.endsWith( ".png" ) ) { - expectedFilename += "/" + expectedName; - } else { - expectedFilename += QString("/%1_%2.png") - .arg( m_config_id ) - .arg( expectedName ); - } - - // The reference snapshot should exist in the data directory for this testcase. - // If it's not there, and we're not in learn mode, we will fail. - if ( (learnMode() == LearnNone || m_auto_mode) && !QFile::exists(expectedFilename) ) { - fail(QString("Reference snapshot '%1' doesn't exist yet. Please manually run test in learn mode.").arg(expectedFilename)); - return; - } - - // Now query AUT for the current snapshot - QImage actualIm( grabImage(queryPath, maskedWidgets) ); - if (actualIm.isNull()) return; - - bool snapshotOk = false; - QDir("/").mkpath(currentDataPath()); - QImage expectedIm(expectedFilename); - - // Now do the actual comparisons. - // If we are not in learn mode, a difference in snapshots will cause a failure. - // If we are in learn mode, a difference will cause a user prompt to accept the new snapshot. - // If we are in learn-all mode, the prompt will be displayed every time. - - if ( (learnMode() != LearnAll || m_auto_mode) && QFile::exists(expectedFilename) ) { - snapshotOk = imagesAreEqual(actualIm, expectedIm); - } - - if ( !m_auto_mode && !snapshotOk && learnMode() != LearnNone ) { - if ( learnImage(actualIm, expectedIm, comment) ) { - QFile::remove(expectedFilename); - if ( !actualIm.save(expectedFilename, "PNG", 0) ) { - QWARN(QString("Failed to save image to %1!").arg(expectedFilename).toLatin1()); - } else { - QTestIDE::instance()->newTestData(expectedFilename); - } - snapshotOk = true; - } else { - fail( "New image not accepted by tester" ); - return; - } - } - - if (!snapshotOk) { - // Failure, so rename the snapshot to identify it for future reference - expectedFilename.replace(".png", "_failure.png"); - if ( !actualIm.save(expectedFilename, "PNG", 0) ) { - QWARN(QString("Failed to save failure pixmap to %1!").arg(expectedFilename).toLatin1()); - } - fail( "Snapshots are not the same" ); - return; - } - - /* By using compare, we go through the "expected failure" processing. */ - /* Without this, we won't get XPASS */ - QTest::compare_helper( true, "Snapshots are the same", qPrintable(currentFile()), currentLine() ); -} - -/*! - Compares the widget specified by \a {queryPath} against the reference snapshot \a expectedName. - - \a maskedWidgets is a list of query paths specifying widgets to be excluded from the snapshot. This allows constantly changing widgets to be hidden from view while the snapshot is taken. Each masked widget is replaced by a black rectangle, and any overlapping widgets will also be concealed. - - Returns true if the images match, or false otherwise. - - The reference snapshot can be one previously learned using verifyImage(), or an image saved using saveScreen(), in which case - the .png filename extension must be specified. - - \sa verifyImage(), saveScreen() -*/ -bool QSystemTest::compareImage( const QString &expectedName, const QString &queryPath, const QStringList &maskedWidgets ) -{ - if (runAsManualTest()) { - manualTestData( quote(expectedName) + " looks similar to " + quote(queryPath) ); - return true; - } - - // Determine the filename - // If the function was passed an explicit filename (indicated by an extension) it will be used directly - // otherwise system specific values are prepended to the name. - QString expectedFilename = currentDataPath(); - if ( expectedName.endsWith( ".png" ) ) { - expectedFilename += "/" + expectedName; - } else { - expectedFilename += QString("/%1_%2.png") - .arg( m_config_id ) - .arg( expectedName ); - } - - // The reference snapshot should exist in the data directory for this testcase. - if ( !QFile::exists(expectedFilename) ) { - fail(QString("Reference snapshot '%1' doesn't exist.").arg(expectedFilename)); - return false; - } - - // Now query AUT for the current snapshot - QImage actualIm( grabImage(queryPath, maskedWidgets) ); - if (queryFailed()) return false; - - QImage expectedIm(expectedFilename); - - // Now do the actual comparisons. - return imagesAreEqual(actualIm, expectedIm); -} - -/*! - Reads \a srcFile from the test system and returns its contents. - if \a srcFile contains environment variables, they will be expanded on the test system. - - \sa {File Management}, getFile(), putData(), putFile() -*/ -QString QSystemTest::getData( const QString &srcFile ) -{ - if (runAsManualTest()) { - manualTestData( "the contents of file " + quote(srcFile) ); - return "MAGIC_DATA"; - } - - QTestMessage message("getFile"); - message["path"] = srcFile; - - QTestMessage reply; - if (!queryPassed( "OK", "", BT(message), "", &reply )) return QString(); - if (!reply["getFile"].isValid()) { - fail("No data in reply to getData"); - return QString(); - } - return reply["getFile"].toString(); -} - -/*! - \internal - Returns image size of image specified in \a srcFile. - if \a srcFile contains environment variables, they will be expanded on the test system. - - Note: QSize does not have toString(), see QSize docs for methods returning common types. - - Example: - \code - // Find the image size of specified image - var imgSize = getImageSize( documentsPath() + "image/foo.jpg" ); - prompt( "Image size is: " + imgSize.width() + " by " + imgSize.height() + ".\n" ); - \endcode -*/ -QSize QSystemTest::getImageSize( const QString &srcFile) -{ - if (runAsManualTest()) { - manualTestData( "the image size of " + quote(srcFile) ); - return QSize(); - } - - QTestMessage message("getImageSize"); - message["path"] = srcFile; - - QTestMessage reply; - if (!queryPassed( "OK", "", BT(message), "", &reply )) return QSize(); - if (!reply["getImageSize"].isValid()) { - fail("No data in reply to getImageSize"); - return QSize(); - } - return reply["getImageSize"].value<QSize>(); -} -/*! - Returns geometry of the widget specified in \a queryPath, with position (x,y) co-ordinates being global. - Note: QRect does not have toString() method, refer to QRect docs for methods returning common types. - - Example: - \code - // pass the test if widgets do not overlap - var first_widget = getGeometry("Button1"); - var second_widget = getGeometry("Button2"); - // intersects returns true on overlap, false when not; verify causes test to fail on false - verify( !first_widget.intersects(second_widget), "Specified widgets overlap."); - \endcode - Example two - a non-mainstream situation: - - select() may work in an undefined manner with custom widgets/items, implementing custom select() methods isn't ideal - each would require writing and testing. - On a device with a primary input method of mouse/touchscreen there may not be key code mapping for keys which don't exist - therefore mouse events should be used. However devices may have different geometry, and widget geometry can change between invocations. The example below uses mouseClick() without prior geometry knowledge, though a way is needed to determine where to click, the example shows mouseClick() in the middle of an area defined by the 4th col and 4th row in a uniform grid of the area of the active widget. - \code - // mouseClick() a widget or item with a fixed position inside its parent widget - var geo = getGeometry(); - var select_x = geo.x() + (( geo.width() / 8) * 7); - var select_y = geo.y() + (( geo.height() / 8) * 7); - mouseClick(select_x, select_y); - \endcode - - \sa select(), mouseClick(), QRect -*/ -QRect QSystemTest::getGeometry( const QString &queryPath ) -{ - if (runAsManualTest()) { - manualTestData( "the geometry of " + quote(queryPath) ); - return QRect(); - } - - QRect ret; - return queryWithReturn(ret, "getGeometry", queryPath); -} - -/*! - Retrieves \a srcFile from the test system and copies it to \a destFile on the local machine. - if \a srcFile contains environment variables, they will be expanded on the test system. - - Example: - \code - // Copy a settings file to the local machine - getFile("$HOME/Settings/foo.conf", "/tmp/foo.conf" ); - \endcode - - \sa {File Management}, getData(), putData(), putFile() -*/ -void QSystemTest::getFile( const QString &srcFile, const QString &destFile ) -{ - if (runAsManualTest()) { - manualTest( "copy file " + quote(srcFile) + " from the tested device to " + quote(destFile) + " on your local machine" ); - return; - } - - QTestMessage message("getFile"); - message["path"] = srcFile; - - QTestMessage reply; - if (!queryPassed( "OK", "", BT(message), "", &reply )) return; - if (!reply["getFile"].isValid()) { - reply["status"] = "ERROR_MISSING_DATA"; - QFAIL(reply); - } - QByteArray data = reply["getFile"].toByteArray(); - QFile out(destFile); - if (!out.open(QIODevice::WriteOnly|QIODevice::Truncate)) - QFAIL( "Couldn't open local file '" + destFile + "'"); - qint64 b; - for (b = out.write(data); b < data.size() && -1 != b; ++b) { - qint64 this_b = out.write(data.mid(b)); - if (-1 == this_b) b = -1; - else b += this_b; - } - if (-1 == b) - QFAIL( "Couldn't write to local file '" + destFile + "'"); -} - -/*! - Transfers \a srcFile from the local machine and copies it to \a destFile on the test system. - if \a destFile contains environment variables, they will be expanded on the test system. - - By default, the file permissions of the destination file will be set to those of the source - file. This can be overridden by specifying \a permissions. - - Example: - \code - // Force test system to use certain settings - putFile("testdata/my_settings.conf", "$HOME/Settings/foo.conf"); - - // Specify file permissions - putFile("testdata/my_file", "$HOME/my_file", QFile.WriteOwner | QFile.ReadOwner | QFile.ReadOther); - \endcode - - \sa {File Management}, putData() -*/ -void QSystemTest::putFile( const QString &srcFile, const QString &destFile, QFile::Permissions permissions ) -{ - if (runAsManualTest()) { - QString perm; - if (permissions == 0) { - perm = " using the current file permissions"; - } else { - perm = " using permissions: "; - if ((permissions & QFile::ReadOwner) > 0) perm += "ReadOwner, "; - if ((permissions & QFile::WriteOwner) > 0) perm += "WriteOwner, "; - if ((permissions & QFile::ExeOwner) > 0) perm += "ExeOwner, "; - if ((permissions & QFile::ReadUser) > 0) perm += "ReadUser, "; - if ((permissions & QFile::WriteUser) > 0) perm += "WriteUser, "; - if ((permissions & QFile::ExeUser) > 0) perm += "ExeUser, "; - if ((permissions & QFile::ReadGroup) > 0) perm += "ReadGroup, "; - if ((permissions & QFile::WriteGroup) > 0) perm += "WriteGroup, "; - if ((permissions & QFile::ExeGroup) > 0) perm += "ExeGroup, "; - if ((permissions & QFile::ReadOther) > 0) perm += "ReadOther, "; - if ((permissions & QFile::WriteOther) > 0) perm += "WriteOther, "; - if ((permissions & QFile::ExeOther) > 0) perm += "ExeOther, "; - if (perm.endsWith(", ")) perm = perm.left(perm.length()-2); - } - manualTest( "copy file " + quote(srcFile) + " from your local machine to " + quote(destFile) + " on the tested device" + perm); - return; - } - - QFile f(srcFile); - if (!f.open(QIODevice::ReadOnly)) - QFAIL( "Couldn't open '" + srcFile + "'" ); - - putData(f.readAll(), destFile, permissions ? permissions : f.permissions()); -} - -/*! - Reads text from the specified \a file and returns the contents as a QString. - - This can be useful when prompting the user with larger amounts of text. - - \sa {File Management}, prompt() -*/ -QString QSystemTest::readLocalFile( const QString &file ) -{ - QFile f(file); - QString ret; - if (!f.open(QIODevice::ReadOnly)) { - setQueryError( "Couldn't open '" + file + "'" ); - return ret; - } - ret = f.readAll(); - return ret; -} - -/*! - Transfers \a data from the local machine and copies it to \a destFile on the test system. - if \a destFile contains environment variables, they will be expanded on the test system. - The file permissions of the destination file can be specified using \a permissions. - - \sa {File Management}, putFile() -*/ -void QSystemTest::putData( const QByteArray &data, const QString &destFile, QFile::Permissions permissions ) -{ - QTestMessage message("putFile"); - message["path"] = destFile; - message["data"] = data; - if (permissions) { - message["permissions"] = static_cast<int>(permissions); - } - queryPassed("OK", "", BT(message)); -} - -/*! - Delete \a path from the test system. Can be a file, or can be a directory - tree, in which case the entire tree is recursively deleted. - If \a path contains environment variables, they will be expanded on the - test system. - - Example: - \code - // Force test system to start with clean settings - deletePath("$HOME/Settings"); - \endcode - - \sa {File Management} -*/ -void QSystemTest::deletePath( const QString &path ) -{ - if (runAsManualTest()) { - manualTest( "delete the contents of path " + quote(path) + " on your device" ); - return; - } - - QTestMessage message("deletePath"); - message["path"] = path; - queryPassed( "OK", "", BT(message) ); -} - -/*! - Invoke method \a method on object \a queryPath on the test system. - Invokable methods include only Qt signals and slots. - - The method will be invoked using the Qt connection type \a type. This can - almost always be Qt::AutoConnection, but in a few cases Qt.QueuedConnection may - be necessary. - - The optional arguments \a arg0, \a arg1, \a arg2, \a arg3, \a arg4, \a arg5, \a arg6, - \a arg7, \a arg8 and \a arg9 will be passed to the method if given. - - Returns true if the method could be invoked, false otherwise. - - Example: - \code - // Hide this field because it keeps changing and we want a snapshot - verify( invokeMethod("Time", "setVisible(bool)", Qt.AutoConnection, false) ); - verifyImage("good_snapshot"); - // Put the field back - verify( invokeMethod("Time", "setVisible(bool)", Qt.AutoConnection, true) ); - \endcode - - \sa {Query Paths}, {Querying Objects} -*/ -bool QSystemTest::invokeMethod( const QString &queryPath, const QString &method, Qt::ConnectionType type, - const QVariant &arg0, const QVariant &arg1, const QVariant &arg2, - const QVariant &arg3, const QVariant &arg4, const QVariant &arg5, - const QVariant &arg6, const QVariant &arg7, const QVariant &arg8, - const QVariant &arg9 ) -{ - if (runAsManualTest()) { - manualTestData( "invoke method " + quote(method) + " on " + quote(queryPath) ); - return true; - } - - QTestMessage message("invokeMethod"); - message["method"] = method; - message["returns"] = false; - message["conntype"] = (int)type; - - QVariantList argList; - if (arg0.isValid()) argList << arg0; - if (arg1.isValid()) argList << arg1; - if (arg2.isValid()) argList << arg2; - if (arg3.isValid()) argList << arg3; - if (arg4.isValid()) argList << arg4; - if (arg5.isValid()) argList << arg5; - if (arg6.isValid()) argList << arg6; - if (arg7.isValid()) argList << arg7; - if (arg8.isValid()) argList << arg8; - if (arg9.isValid()) argList << arg9; - - message["args"] = argList; - - QTestMessage reply; - if (!queryPassed( QStringList("OK"), QStringList() - << "ERROR_NO_METHOD" - << "ERROR_METHOD_NOT_INVOKABLE" - << "ERROR_WRONG_ARG_COUNT" - << "ERROR_NO_RETURN" - << "ERROR_IN_INVOKE", BT(message), queryPath, &reply)) return false; - - return true; -} - -/*! - \overload - Invokes the given method using connection type Qt.AutoConnection. -*/ -bool QSystemTest::invokeMethod( const QString &queryPath, const QString &method, - const QVariant &arg0, const QVariant &arg1, const QVariant &arg2, - const QVariant &arg3, const QVariant &arg4, const QVariant &arg5, - const QVariant &arg6, const QVariant &arg7, const QVariant &arg8, - const QVariant &arg9 ) -{ - return invokeMethod(queryPath, method, Qt::AutoConnection, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9 ); -} - -/*! - Set the Qt property named \a name on object \a queryPath to value \a value - on the test system. - - Errors can occur in this function. - - Example: - \code - // Set the text of this field without simulating key presses - setProperty("Name", "text", "Billy Jones"); - \endcode - - \sa {Query Paths}, {Querying Objects} -*/ -void QSystemTest::setProperty( const QString &queryPath, const QString &name, const QVariant &value ) -{ - if (runAsManualTest()) { - manualTest( "set property " + quote(name) + " to " + quote(value.toString()) ); - return; - } - - QTestMessage message("setProperty"); - message["property"] = name; - message["value"] = value; - - queryPassed( "OK", "", BT(message), queryPath ); -} - -/*! - Get the value of the Qt property named \a name on object \a queryPath on the test system. - - Example: - \code - // Get the text of this field without using getText() - var t = getProperty("Name", "text").toString(); - \endcode - - \sa {Query Paths}, {Querying Objects} -*/ -QVariant QSystemTest::getProperty( const QString &queryPath, const QString &name ) -{ - if (runAsManualTest()) { - manualTest( "property " + quote(name) + " from " + quote(queryPath) ); - return QVariant("MAGIC_DATA"); - } - - QTestMessage message("getProperty"); - message["property"] = name; - - QVariant out; - - QTestMessage reply; - if (!queryPassed( "OK", "", BT(message), queryPath, &reply)) return out; - - return reply["getProperty"]; -} - -/*! - Returns the signatures of the widgets that have \a property matching \a value. - This can be used to identify widgets that do not have an associated label text. - - In addition to normal QObject properties, "inherits" and "className" may also - be used, with the class specified as a string. - - Example: - \code - // Select the button with the tool tip "Quit" - // assumes that only one widget will match - var button = findByProperty("toolTip", "Quit"); - activate(button); - \endcode - - If more than one widget matches, the list returned is sorted by widget position. - If no matching widgets are found, the list returned is empty, but the test does - not fail. Use findWidget() to cause a test failure when no matching widgets are found. - - \sa findWidget(), signature(), {Query Paths}, {Querying Objects} -*/ -QStringList QSystemTest::findByProperty( const QString &property, const QVariant &searchValue ) -{ - if (runAsManualTest()) { - manualTest( "the property " + quote(property) + " of " + quote(searchValue.toString()) ); - return QStringList("MAGIC_DATA"); - } - - QTestMessage message("findByProperty"); - message["property"] = property; - message["searchValue"] = searchValue; - - QStringList out; - QTestMessage reply; - if (!queryPassed( "OK", "", BT(message), "", &reply)) return out; - out = reply["findByProperty"].toStringList(); - return out; -} - -/*! - Returns the signatures of the widgets that match all of the property values - specified in \a searchValues. - - This can be used to identify widgets that do not have an associated label text. - - Example: - \code - // Select the button with the tool tip "Quit" - // assumes that only one widget will match - var button = findByProperty( {className: "QToolButton", - toolTip: "Quit"} ); - activate(button); - \endcode - - If more than one widget matches, the list returned is sorted by widget position. - If no matching widgets are found, the list returned is empty, but the test does - not fail. Use findWidget() to cause a test failure when no matching widgets are found. - - \sa findWidget(), signature(), {Query Paths}, {Querying Objects} -*/ -QStringList QSystemTest::findByProperty( const QVariantMap &searchValues ) -{ - QTestMessage message("findByProperties"); - message["searchValues"] = searchValues; - - QStringList out; - QTestMessage reply; - if (!queryPassed( "OK", "", BT(message), "", &reply)) return out; - out = reply["findByProperties"].toStringList(); - return out; -} - -/*! - Returns the signatures of the widgets that have \a property matching \a value. - - This function is the same as findByProperty(), but results in a test failure - if no matching widgets are found. - - \sa findByProperty() -*/ -QStringList QSystemTest::findWidget( const QString &property, const QVariant &searchValue ) -{ - QStringList ret = findByProperty(property, searchValue); - if (ret.isEmpty()) { - fail("No widget found with specified property."); - } - return ret; -} - -/*! - Returns the signatures of the widgets that match all of the property values - specified in \a searchValues. - - This function is the same as findByProperty(), but results in a test failure - if no matching widgets are found. - - \sa findByProperty() -*/ -QStringList QSystemTest::findWidget( const QVariantMap &searchValues ) -{ - QStringList ret = findByProperty(searchValues); - if (ret.isEmpty()) { - fail("No widget found with specified properties."); - } - return ret; -} - -/*! - Retrieves a QSettings settings value from the test system located in \a file, settings group \a group, key \a key. - If \a file contains environment variables, they will be expanded on the test system. - - Example: - \code - // What's our primary input mode? - var primaryInput = getSetting("$QPEDIR/etc/defaultbuttons.conf", "Device", "PrimaryInput"); - \endcode - - \sa setSetting(), QSettings -*/ -QVariant QSystemTest::getSetting( const QString &file, const QString &group, const QString &key ) -{ - return getSetting(QString(), QString(), file, group, key); -} - -/*! - Retrieves a QSettings settings value from the test system located in the settings file for - organization \a organization and application \a application, as passed to the QSettings - constructor. The settings value retrieved will be group \a group, key \a key. - - \sa setSetting(), QSettings -*/ -QVariant QSystemTest::getSetting( const QString &organization, const QString &application, const QString &group, const QString &key ) -{ - return getSetting(organization, application, QString(), group, key); -} - -/*! - Set a QSettings settings \a value on the test system located in \a file, settings group \a group, key \a key. - - Example: - \code - // Turn on english and deutsch input languages - setSetting("$HOME/Settings/Trolltech/locale.conf", "Language", "InputLanguages", "en_US de" ); - \endcode - - \sa getSetting(), QSettings -*/ -void QSystemTest::setSetting( const QString &file, const QString &group, const QString &key, const QVariant &value ) -{ - setSetting(QString(), QString(), file, group, key, value); -} - -/*! - Set a QSettings settings \a value on the test system located in the settings file - for the given \a organization and \a application, as passed to a QSettings constructor. - The value set will be in settings group \a group, key \a key. - - \sa getSetting(), QSettings -*/ -void QSystemTest::setSetting( const QString &organization, const QString &application, const QString &group, const QString &key, const QVariant &value ) -{ - setSetting(organization, application, QString(), group, key, value); -} - -static QStringList filter = QStringList(); - - -/*! \internal */ -void QSystemTest::applicationStandardOutput(QList<QByteArray> const& lines) -{ - foreach (QByteArray const& line, lines) - QDebug(QtDebugMsg) << line; -} - -/*! \internal */ -void QSystemTest::applicationStandardError(QList<QByteArray> const& lines) -{ - foreach (QByteArray const& line, lines) - QDebug(QtDebugMsg) << line; -} - -/*! - Switches the 'strict syntax' checking mode for the System test to \a on. - - In strict mode the following commands are no longer allowed and will cause an immediate failure: - \list - \i keyClick() - \i keyPress() - \i keyRelease() - \i keyClickHold() - \endlist - - Strict mode also verifies that every 'Title' change is covered by a call to waitForTitle(): any - action that results in a Dialog to be shown (with a different title) will cause a test failure - unless a waitForTitle() is called on the next line of the test script. -*/ -void QSystemTest::strict( bool on ) -{ - m_strict_mode = on; -} - -/*! - Simulates a \a key press for the application specified by \a queryPath. - \a key is a Qt::Key describing the key to be pressed. - - Example: - \code - // Press (do not release) F23 key in current app - keyPress( Qt.Key_F23 ); - \endcode - - \sa {Query Paths}, {Keypad Simulation} -*/ -void QSystemTest::keyPress( Qt::Key key, const QString &queryPath ) -{ - if (m_strict_mode) QFAIL( "ERROR: keyPress is not allowed in strict mode" ); - - QTestMessage message("keyPress"); - message["key"] = (int)key; - QString qp = queryPath; - if (qp.isEmpty()) qp = ""; - queryPassed( "OK", "", BT(message), qp ); -} - -/*! - Simulates a \a key release for the application specified by \a queryPath. - \a key is a Qt::Key describing the key to be released. - - Example: - \code - // Release Up key in current app - keyRelease( Qt.Key_Up ); - \endcode - - \sa {Query Paths}, {Keypad Simulation} -*/ -void QSystemTest::keyRelease( Qt::Key key, const QString &queryPath ) -{ - if (m_strict_mode) QFAIL( "ERROR: keyRelease is not allowed in strict mode" ); - - QTestMessage message("keyRelease"); - message["key"] = (int)key; - QString qp = queryPath; - if (qp.isEmpty()) qp = ""; - queryPassed( "OK", "", BT(message), qp ); -} - -/*! - Simulates a \a key click (press and release) for the application specified by \a queryPath. - \a key is a string describing the key to be released. - - Example: - \code - // Go right 5 times, then select - for (int i = 0; i < 5; ++i) keyClick( Qt.Key_Right ); - keyClick( Qt.Key_Select ); - \endcode - - \sa {Query Paths}, {Keypad Simulation} -*/ -void QSystemTest::keyClick( Qt::Key key, const QString &queryPath ) -{ - if (QSystemTest::runAsManualTest()) { - manualTest( QString("click key %1 in application %2") - .arg(QKeySequence(key).toString()) - .arg(quote(queryPath)) ); - return; - } - - if (m_strict_mode) QFAIL( "ERROR: keyClick is not allowed in strict mode" ); - - QTestMessage message("keyClick"); - message["key"] = (int)key; - QString qp = queryPath; - if (qp.isEmpty()) qp = ""; - queryPassed( "OK", "", BT(message), qp ); -} - -/*! - Simulates a \a key click and hold (press + wait + release) for \a queryPath. - The interval between press and release is set in milliseconds by \a duration. - - Example: - \code - // Hold hangup key to bring up shutdown app - keyClickHold(Qt.Key_Hangup, 3000); - \endcode - - \sa {Query Paths}, {Keypad Simulation} -*/ -void QSystemTest::keyClickHold( Qt::Key key, int duration, const QString &queryPath ) -{ - if (m_strict_mode) QFAIL( "ERROR: keyClickHold is not allowed in strict mode" ); - - m_keyclickhold_key = key; - m_keyclickhold_path = queryPath; - - QTestMessage message("keyPress"); - message["key"] = (int)key; - message["duration"] = duration; - QString qp = queryPath; - if (qp.isEmpty()) qp = ""; - queryPassed( "OK", "", BT(message), qp ); - - if (queryFailed()) return; - - wait(duration); - - if (m_keyclickhold_key) { - m_keyclickhold_key = (Qt::Key)0; - m_keyclickhold_path = ""; - - keyRelease(key, queryPath); - } -} - -/*! - Simulates a mouse click / touchscreen tap at co-ordinates ( \a x, \a y ). - - Example: - \code - mouseClick(200, 300); - \endcode - - \sa {Query Paths}, {Mouse / Touchscreen Simulation} -*/ -void QSystemTest::mouseClick( int x, int y, QFlags<Qt::MouseButton> buttons ) -{ - mouseClick(QPoint(x, y), buttons); -} - -/*! - Simulates a mouse click / touchscreen tap at \a point. - - Example: - \code - mouseClick( new QPoint(200, 300) ); - \endcode - - \sa {Query Paths}, {Mouse / Touchscreen Simulation} -*/ -void QSystemTest::mouseClick( const QPoint &point, QFlags<Qt::MouseButton> buttons ) -{ - if (QSystemTest::runAsManualTest()) { - manualTestData( QString("position (x,y) %1,%2").arg(point.x()).arg(point.y()), true); - manualTest( QString("%1 click the mouse on MAGIC_DATA") - .arg(mouseButtons(buttons))); - return; - } - - if (m_strict_mode) QFAIL( "ERROR: mouseClick is not allowed in strict mode" ); - QTestMessage message("mouseClick"); - message["pos"] = point; - message["buttons"] = (int)buttons; - queryPassed( "OK", "", BT(message) ); -} - -/*! - Simulates a mouse click / touchscreen tap at the center of the widget - specified by \a queryPath. - - Example: - \code - // Click on Accept button - mouseClick("Accept"); - \endcode - - \sa {Query Paths}, {Mouse / Touchscreen Simulation} -*/ -void QSystemTest::mouseClick( const QString &queryPath, QFlags<Qt::MouseButton> buttons ) -{ - if (QSystemTest::runAsManualTest()) { - manualTest( QString("%1 click the mouse on %2") - .arg(mouseButtons(buttons)).arg(quote(queryPath))); - return; - } - - if (m_strict_mode) QFAIL( "ERROR: mouseClick is not allowed in strict mode" ); - QTestMessage message("mouseClick"); - message["buttons"] = (int)buttons; - queryPassed( "OK", "", BT(message), queryPath ); - wait(200); -} - -/*! - Simulates a mouse click / touchscreen tap at co-ordinates ( \a x, \a y ), - with a custom \a duration in milliseconds between press and release. - - Example: - \code - // Hold at (200, 300) for three seconds - mouseClickHold(200, 300, 3000); - \endcode - - \sa {Query Paths}, {Mouse / Touchscreen Simulation} -*/ -void QSystemTest::mouseClickHold( int x, int y, int duration, QFlags<Qt::MouseButton> buttons ) -{ - mouseClickHold(QPoint(x, y), duration, buttons); -} - -/*! - Simulates a mouse click / touchscreen tap at \a point, - with a custom \a duration in milliseconds between press and release. - - Example: - \code - // Hold at (200, 300) for three seconds - mouseClickHold( new QPoint(200, 300), 3000 ); - \endcode - - \sa {Query Paths}, {Mouse / Touchscreen Simulation} -*/ -void QSystemTest::mouseClickHold( const QPoint &point, int duration, QFlags<Qt::MouseButton> buttons ) -{ - if (QSystemTest::runAsManualTest()) { - manualTest( QString("%1 click - and HOLD - the mouse on position (x,y) %2,%3 for approximately %4 milliseconds, and then release") - .arg(mouseButtons(buttons)).arg(point.x()).arg(point.y()).arg(duration)); - return; - } - - if (m_strict_mode) QFAIL( "ERROR: mouseClickHold is not allowed in strict mode" ); - - mousePress(point, buttons); - wait(duration); - mouseRelease(point, buttons); -} - -/*! - Simulates a mouse click / touchscreen tap at the center of the widget - specified by \a queryPath, with a custom \a duration in milliseconds - between press and release. - - Example: - \code - // Hold on the "Shutdown" button for three seconds - mouseClickHold("Shutdown", 3000); - \endcode - - \sa {Query Paths}, {Mouse / Touchscreen Simulation} -*/ -void QSystemTest::mouseClickHold( const QString &queryPath, int duration, QFlags<Qt::MouseButton> buttons ) -{ - if (QSystemTest::runAsManualTest()) { - manualTest( QString("%1 click - and HOLD - the mouse on %2 for approximately %3 milliseconds, and then release") - .arg(mouseButtons(buttons)).arg(quote(queryPath)).arg(duration)); - return; - } - - if (m_strict_mode) QFAIL( "ERROR: mouseClickHold is not allowed in strict mode" ); - - mousePress(queryPath, buttons); - wait(duration); - mouseRelease(queryPath, buttons); -} - -/*! - Simulates a mouse / touchscreen press at co-ordinates ( \a x, \a y ). - - Example: - \code - mousePress(200, 300); - \endcode - - \sa {Query Paths}, {Mouse / Touchscreen Simulation} -*/ -void QSystemTest::mousePress( int x, int y, QFlags<Qt::MouseButton> buttons ) -{ - mousePress(QPoint(x, y), buttons); -} - -/*! - Simulates a mouse / touchscreen press at \a point. - - Example: - \code - mousePress( new QPoint(200, 300) ); - \endcode - - \sa {Query Paths}, {Mouse / Touchscreen Simulation} -*/ -void QSystemTest::mousePress( const QPoint &point, QFlags<Qt::MouseButton> buttons ) -{ - if (QSystemTest::runAsManualTest()) { - manualTest( QString("%1 press - and HOLD - the mouse on position (x,y) %2,%3") - .arg(mouseButtons(buttons)).arg(point.x()).arg(point.y())); - return; - } - - if (m_strict_mode) QFAIL( "ERROR: mousePress is not allowed in strict mode" ); - - QTestMessage message("mousePress"); - message["pos"] = point; - message["buttons"] = (int)buttons; - queryPassed( "OK", "", BT(message) ); -} - -/*! - Simulates a mouse / touchscreen press at the center of the widget - specified by \a queryPath. - - Example: - \code - // Press "Edit" button - mousePress("Edit"); - \endcode - - \sa {Query Paths}, {Mouse / Touchscreen Simulation} -*/ -void QSystemTest::mousePress( const QString &queryPath, QFlags<Qt::MouseButton> buttons ) -{ - if (QSystemTest::runAsManualTest()) { - manualTest( QString("%1 press - and HOLD - the mouse on %2") - .arg(mouseButtons(buttons)).arg(quote(queryPath))); - return; - } - - if (m_strict_mode) QFAIL( "ERROR: mousePress is not allowed in strict mode" ); - - QTestMessage message("mousePress"); - message["buttons"] = (int)buttons; - queryPassed( "OK", "", BT(message), queryPath ); -} - -/*! - Simulates a mouse / touchscreen release at co-ordinates ( \a x, \a y ). - - Example: - \code - mouseRelease(200, 300); - \endcode - - \sa {Query Paths}, {Mouse / Touchscreen Simulation} -*/ -void QSystemTest::mouseRelease( int x, int y, QFlags<Qt::MouseButton> buttons ) -{ - mouseRelease(QPoint(x, y), buttons); -} - -/*! - Simulates a mouse / touchscreen release at \a point. - - Example: - \code - mouseRelease( new QPoint(200, 300) ); - \endcode - - \sa {Query Paths}, {Mouse / Touchscreen Simulation} -*/ -void QSystemTest::mouseRelease( const QPoint &point, QFlags<Qt::MouseButton> buttons ) -{ - if (QSystemTest::runAsManualTest()) { - manualTest( QString("%1 release the mouse on position (x,y) %2,%3") - .arg(mouseButtons(buttons)).arg(point.x()).arg(point.y())); - return; - } - - if (m_strict_mode) QFAIL( "ERROR: mouseRelease is not allowed in strict mode" ); - - QTestMessage message("mouseRelease"); - message["buttons"] = (int)buttons; - message["pos"] = point; - queryPassed( "OK", "", BT(message) ); -} - -/*! - Simulates a mouse / touchscreen release at the center of the widget - specified by \a queryPath. - - Example: - \code - // Release mouse over "Edit" button - mouseRelease("Edit"); - \endcode - - \sa {Query Paths}, {Mouse / Touchscreen Simulation} -*/ -void QSystemTest::mouseRelease( const QString &queryPath, QFlags<Qt::MouseButton> buttons ) -{ - if (QSystemTest::runAsManualTest()) { - manualTest( QString("%1 release the mouse on %2") - .arg(mouseButtons(buttons)).arg(quote(queryPath))); - return; - } - - if (m_strict_mode) QFAIL( "ERROR: mouseRelease is not allowed in strict mode" ); - - QTestMessage message("mouseRelease"); - message["buttons"] = (int)buttons; - queryPassed( "OK", "", BT(message), queryPath ); -} - -/*! - Simulates \a value being entered into the widget specified by \a queryPath. - - Some widgets go into an editing mode when entering text and need to be taken - out of the editing mode by e.g. a Qt::Key_Select or by navigating to - another field in the dialog. By default, enter() will automatically take whatever - action is necessary to commit the text and leave edit mode. Set \a mode to NoCommit to - override this. - - Example: - \code - // Enter my job in "Occupation" field - enter( "Dog Walker", "Occupation" ); - - // Enter date of birth in "Birthday" field - enter( new Date(1985, 11, 10), "Birthday" ); - - // Enter start time in "Start" field - enter( new QTime(11, 30), "Start" ); - \endcode - - \sa {Query Paths}, {Keypad Simulation} -*/ -void QSystemTest::enter( const QVariant &value, const QString &queryPath, EnterMode mode ) -{ - if (QSystemTest::runAsManualTest()) { - QString type = value.typeName(); - if (type == "QDate") type = "date"; - else if (type == "QTime" ) type = "time"; - else if (type == "QString" ) type = "string"; - - manualTest( QString("enter %1 %2 in field %3") - .arg(type) - .arg(quote(value.toString())) - .arg(quote(queryPath))); - return; - } - - if (value.isNull()) return; - QTestMessage message("enter"); - message["value"] = value; - - switch (mode) - { - case NoCommit: message["mode"] = "NoCommit"; break; - default: message["mode"] = "Commit"; break; - } - - queryPassed( "OK", "", BT(message), queryPath ); -} - -/*! - Selects the \a item from the application/widget specified by \a queryPath. - This can be used to, e.g., select a certain item from a list widget or combo box. - select() works with widgets which are conceptually a list, including - list views, combo boxes and menus. - - When used with a list widget, the specified item is navigated to and no further - action is taken. - - When used with a combo box, the drop-down list is opened, - the item is selected, and the drop-down list is closed again. - - Items in submenus are denoted using '/' delimiters (e.g., "View/All" means - navigate to the "View" submenu, then the "All" item). Menu items which - have a '/' in their name can be escaped using '\' (e.g. "Add\\/Remove Words"). - - Example: - \code - // Select "Female" from "Gender" field - select("Female", "Gender"); - \endcode - - \sa {Query Paths}, {Keypad Simulation} -*/ -void QSystemTest::select( const QString &item, const QString &queryPath ) -{ - if (m_run_as_manual_test) { - manualTest( "select " + quote(item) + " from " + quote(queryPath)); - return; - } - - if (item.isNull()) return; - QTestMessage message("select"); - message["text"] = item; - queryPassed("OK", "", BT(message), queryPath); - - /* FIXME: this wait should be able to be put in the test widgets. - * Currently it can't because of the new bop problem (bug 194361). - */ - wait((m_demo_mode) ? 1500 : 150); -} - -/*! - Selects the item with \a index from an indexed widget (such as a QAbstractItemView) - specified by \a queryPath. - - This function is lower level than using select(), but is more appropriate when there - are large numbers of items in the view, or the view contains unnamed or ambiguously - named items. - - The \a index is specified as a list of row and column values. - - Example: - \code - // Select item (row 2, column 3) from table view - select( [2, 3], table ); - \endcode - - The index may be hierarchical, in which case the row and column values should be - specified as [row, column, parentRow, parentColumn, ...]. - - \sa select(), selectedIndex() -*/ -void QSystemTest::selectIndex( const QVariantList &index, const QString &queryPath ) -{ - if (m_run_as_manual_test) { - QString index_str = "["; - for (int i=0; i<index.count(); i++) { - index_str += index[i].toString() + ", "; - } - index_str = index_str.left(index_str.length()-2); - index_str += "]"; - - QString example_str = "item"; - if (index.count() >= 2) { - example_str = "<row, column"; - if (index.count() == 3) example_str += ", ..."; - if (index.count() >= 4) example_str += ", parentRow, parentColumn"; - if (index.count() == 5) example_str += ", ..."; - if (index.count() >= 6) example_str += ", ..."; - example_str += ">"; - } - manualTest( "select " + example_str + " " + index_str + " from list " + quote(queryPath) ); - return; - } - - QTestMessage message("selectIndex"); - message["index"] = index; - queryPassed("OK", "", BT(message), queryPath); - - /* FIXME: this wait should be able to be put in the test widgets. - * Currently it can't because of the new bop problem (bug 194361). - */ - wait((m_demo_mode) ? 1500 : 150); -} - - -/*! - Returns the currently selected index of an indexed widget specified by \a queryPath. - The index is returned as an array to QtScript, in the format required for selectIndex(). - - \sa selectIndex() -*/ -QVariantList QSystemTest::getSelectedIndex( const QString &queryPath ) -{ - if (m_run_as_manual_test) { - manualTestData( "the contents of list " + quote(queryPath) ); - return QVariantList(); - } - - QVariantList ret; - return queryWithReturn(ret, "getSelectedIndex", queryPath); -} - -/*! - Activate the widget specified by \a queryPath. - This is typically used to activate button widgets. - - \sa {Query Paths} -*/ -void QSystemTest::activate( const QString &queryPath ) -{ - if (m_run_as_manual_test) { - manualTest( "activate " + quote(queryPath) ); - return; - } - - QTestMessage message("activate"); - queryPassed("OK", "", BT(message), queryPath); - - /* FIXME: this wait should be able to be put in the test widgets. - * Currently it can't because of the new bop problem (bug 194361). - */ - wait((m_demo_mode) ? 1500 : 150); -} - -/*! - Make sure the specified \a item is visible in the widget specified by \a queryPath. - The action taken depends on the widget, but may for example involve moving the - widget's scrollbars. - - \sa {Query Paths} -*/ -void QSystemTest::ensureVisible( const QString &item, const QString &queryPath ) -{ - if (m_run_as_manual_test) { - manualTest( "verify item " + quote(item) + " is visible in " + quote(queryPath) ); - return; - } - - if (item.isNull()) return; - QTestMessage message("ensureVisible"); - message["item"] = item; - queryPassed("OK", "", BT(message), queryPath); - - /* FIXME: this wait should be able to be put in the test widgets. - * Currently it can't because of the new bop problem (bug 194361). - */ - wait((m_demo_mode) ? 1500 : 150); -} - -/*! - Start the specified \a application. - - \a application is the combined path and arguments of a program to launch. - The application must connect to the test framework within \a timeout ms or - the test fails. - - \a flags specifies additional behaviour. - - \sa {Application Management} -*/ -void QSystemTest::startApplication( const QString &application, const QStringList &arguments, int timeout, StartApplicationFlags flags ) -{ - if (m_run_as_manual_test) { - manualTest( "start application '" - + application - + "' " - + arguments.join(" ") ); - return; - } - - QString app = application; - QStringList args = arguments; - - if (!runsOnDevice()) { - if (!device_controller) - device_controller = new Qt4Test::TestController(Qt4Test::TestController::Desktop); - - args = processEnvironment(arguments); - app = processEnvironment(application); - app = which(app); - if (app.isEmpty()) { - fail(QString("Application '%1' not found in PATH (%2)").arg(application).arg(PATH())); - return; - } - - } else { - if (!device_controller) - device_controller = new Qt4Test::TestController(Qt4Test::TestController::Maemo, &ssh_param); - } - - if (device_controller) - device_controller->killApplications(); - - // setup configuration for target, used by configTarget() later - QByteArray defTargetID = qgetenv("QTUITEST_TARGETID"); - if (!defTargetID.isEmpty()) - m_targetID = QString(defTargetID); - - QString reply; - if (device_controller) { - device_controller->startApplication(app, args, true, m_env, reply); -#ifdef QTCREATOR_QTEST - testOutputPane()->append(reply); -#endif - } - - // Give it a little time for the slave to come up. - wait(100); - - if (!connectToAut(timeout)) { - device_controller->killApplications(); - if (reply.isEmpty()) - fail(QString("Could not connect to remote process '%1'").arg(app).arg(reply)); - else - fail(QString("Could not connect to remote process '%1'\nProcess output is '%2'").arg(app).arg(reply)); - } - configTarget(); -} - -/*! - Terminate any application(s) started by the test system. Normally, this won't be necessary - as startApplication will do this for you. - - \sa {startApplication} -*/ -void QSystemTest::killApplication() -{ - if (device_controller) - device_controller->killApplications(); -} - -/*! - Returns true if the widget specified by \a queryPath exists and is currently visible - to the user. - - The widget is considered to be visible to the user if QWidget::visibleRegion() returns - a non-empty region. Thus, isVisible() will return true if even a single pixel of the - widget is unobscured. - - \sa {Query Paths}, {Querying Objects} -*/ -bool QSystemTest::isVisible( const QString &queryPath ) -{ - if (m_run_as_manual_test) { - manualTestData( "'" + queryPath + "' is visible" ); - return true; - } - - bool ret = false; - return queryWithReturn(ret, "isVisible", queryPath); -} - -/*! - The function returns whether the widget specified by \a queryPath is enabled. - - Example: - \code - // Verify the AM/PM field is disabled when using 24 hour format - select("24 hour", "Time format"); - verify( !isEnabled("AM-PM"), "AM-PM field still enabled." ); - \endcode - - \sa {Query Paths}, {Querying Objects} -*/ -bool QSystemTest::isEnabled( const QString &queryPath ) -{ - return getProperty( queryPath, "enabled" ).toBool(); -} - -/*! - \internal - Returns a string of all the visible widgets that are children of the object specified by \a queryPath. - If only the application part of \a queryPath is defined, then all visible widgets for that application - are listed. The string is organized in a tree type hierarchy showing the relationship between - widgets. - - This function is intended to help with the development of testcases. - - \sa {Query Paths} -*/ -QString QSystemTest::activeWidgetInfo() -{ - QString ret; - return queryWithReturn(ret, "activeWidgetInfo", ""); -} - -/*! - Returns the checked state of the checkbox-like widget specified by \a queryPath. - Checkbox-like widgets include QCheckBox and anything inheriting QAbstractButton. - - \sa {Query Paths}, {Querying Objects}, setChecked(), checkState() -*/ -bool QSystemTest::isChecked( const QString &queryPath ) -{ - bool ret = false; - return queryWithReturn(ret, "isChecked", queryPath); -} - -/*! - Returns the checked state of \a item in the widget specified by \a queryPath. - - \sa {Query Paths}, {Querying Objects}, setChecked(), checkState() -*/ -bool QSystemTest::isChecked( const QString &item, const QString &queryPath ) -{ - if (item.isNull()) return false; - QTestMessage message("isChecked"); - QTestMessage reply; - message["item"] = item; - if (!queryPassed("OK", "", BT(message), queryPath, &reply)) return false; - return reply["isChecked"].toBool(); -} - -/*! - Based on the value of \a doCheck checks or un-checks a checkbox-like widget specified by \a queryPath. - Checkbox-like widgets include QCheckBox and anything inheriting QAbstractButton. - - \sa {Query Paths}, {Querying Objects}, isChecked(), setCheckState() -*/ -void QSystemTest::setChecked( bool doCheck, const QString &queryPath) -{ - QTestMessage message("setChecked"); - message["doCheck"] = doCheck; - queryPassed("OK", "", BT(message), queryPath); -} - -/*! - Based on the value of \a doCheck checks or un-checks \a item in the widget specified by \a queryPath. - - \sa {Query Paths}, {Querying Objects}, isChecked(), setCheckState() -*/ -void QSystemTest::setChecked( bool doCheck, const QString &item, const QString &queryPath) -{ - QTestMessage message("setChecked"); - message["doCheck"] = doCheck; - message["item"] = item; - queryPassed("OK", "", BT(message), queryPath); -} - -/*! - Returns the checked state of the checkbox-like widget specified by \a queryPath. - Checkbox-like widgets include QCheckBox and anything inheriting QAbstractButton. - - \sa {Query Paths}, {Querying Objects}, isChecked(), setCheckState() -*/ -int QSystemTest::checkState( const QString &queryPath ) -{ - int ret = Qt::Unchecked; - return queryWithReturn(ret, "checkState", queryPath); -} - -/*! - Sets the check state of a checkbox-like widget specified by \a queryPath to \a state. - Checkbox-like widgets include QCheckBox and anything inheriting QAbstractButton. - - Example: - \code - // Set tri-state button to partially checked state - setCheckState(Qt.PartiallyChecked, "Tri-state button"); - \endcode - - \sa {Query Paths}, {Querying Objects}, checkState(), setChecked() -*/ -void QSystemTest::setCheckState( int state, const QString &queryPath) -{ - QTestMessage message("setCheckState"); - message["state"] = state; - queryPassed("OK", "", BT(message), queryPath); -} - -/*! - Returns the signature of the widget that is associated with \a labelText. - - If \a offset is a number != 0 the query will return the n'th next or previous widget (excluding labels). The widgets are ordered from - top to bottom, left to right. A positive offset indicates a widget to the right or below, a negative offset indicates a widget to - the left or above the label. - - This function can be used for situations where a field doesn't have a label associated with it. - - \sa {Query Paths}, {Querying Objects}, {QObject::inherits()} -*/ -QString QSystemTest::signature( const QString &labelText, int offset ) -{ - QTestMessage message("widget"); - message["offset"] = offset; - QTestMessage reply; - if (!queryPassed("OK", "", BT(message), labelText, &reply)) return ""; - return reply["widget"].toString(); -} - -/*! - List the contents of directory \a dir on the test system, applying \a filters to the listing. - If \a dir contains environment variables, they will be expanded on the test system. - - The returned listing will be relative to \a dir. - - Example: - \code - // Delete entire contents of Documents directory on the test system - var list = getDirectoryEntries( documentsPath(), QDir.AllEntries); - for (var i = 0; i < list.length; ++i) { - deletePath( documentsPath() + list[i]); - } - \endcode - - \sa QDir::entryList(), {File Management} -*/ -QStringList QSystemTest::getDirectoryEntries( const QString &dir, QDir::Filters filters ) -{ - QTestMessage message("getDirectoryEntries"); - message["path"] = dir; - message["filters"] = (int)filters; - - QStringList out; - QTestMessage reply; - if (!queryPassed( "OK", "", BT(message), "", &reply)) return out; - if (reply["getDirectoryEntries"].isNull()) { - setQueryError("Got no data in response to getDirectoryEntries"); - return out; - } - out = reply["getDirectoryEntries"].toStringList(); - return out; -} - -/*! - Returns the current date and time of the test system. -*/ -QDateTime QSystemTest::getDateTime() -{ - QDateTime ret; - return queryWithReturn(ret, "systemTime", ""); -} - -/*! - Returns true if the test is running on an actual device, and false if it is running locally. -*/ -bool QSystemTest::runsOnDevice() -{ - return ssh_param.host != "127.0.0.1"; -} - -/*! - Wait for \a msecs milliseconds, while still processing events from the event loop. -*/ -void QSystemTest::wait(int msecs) -{ - QTime t; - t.start(); - while (t.elapsed() < msecs) { - qApp->processEvents(); - } -} - -/*! - Returns the currently set Visual Response Time. This time is used in QtUiTest to decide whether the User - Interface is responsive to user events. For instance, after selecting "New Event" from the options menu a user - expects a dialog in which a new event can be entered. If the Application Under Test does not respond in some - visible way within the visual response time, the test will fail. - - By default the visual response time is set to 4 seconds, i.e. any UI that doesn't respond to events within this time - is considered at fault. - - The visibleResponseTime is also used as the default value for some queries such as waitForTitle(). - - \sa setVisibleResponseTime(), waitForTitle() -*/ -int QSystemTest::visibleResponseTime() -{ - return m_visible_response_time; -} - -/*! - Sets the Visual Response Time to \a time. - - \sa visibleResponseTime(), waitForTitle() -*/ -void QSystemTest::setVisibleResponseTime( int time ) -{ - if (m_visible_response_time != time) { - qLog(QtUitest) << "Need to set a new visual response time" ; - } - m_visible_response_time = time; -} - -/*! - Take a full screenshot and save it as \a name. - The screenshot will be placed in the test data directory in PNG format, - and will automatically have .png appended to the name. - - This function is intended to be used as a simple way to automate the - gathering of screenshots, i.e. to be used in documentation and such. - - If a \a queryPath is specified the snapshot will be limited to the Widget - that is identified by the queryPath. - - \sa verifyImage() -*/ -void QSystemTest::saveScreen(const QString &name, const QString &queryPath) -{ - QString cdp = currentDataPath(); - if (!QDir("/").exists(cdp) && !QDir("/").mkpath(cdp)) QFAIL(QString("Path '' didn't exist and I couldn't create it").arg(cdp)); - QImage img; - img = grabImage(queryPath); - if (queryFailed()) return; - if (img.isNull()) QFAIL( "AUT returned a null screenshot." ); - if (!img.save(cdp + "/" + name + ".png", "PNG")) QFAIL(QString("Couldn't save image '%1' to '%2'").arg(name).arg(cdp) ); -} - - -/*! - \fn QSystemTest::expectMessageBox(String title, String text, String option, Number timeout) - Denotes the start of a block of code which, immediately after or during execution, should - cause a message box to pop up with the given \a title and \a text. When the message box - appears, the given menu \a option will be chosen from the message box softmenu bar (if one exists). - - If the message box hasn't appeared by the end of the block of code, the test will - wait until the \a timeout expires. If it still doesn't appear, the current test fails. - - If a message box appears which hasn't been marked as expected, the current test fails. - - Example: - \code - // Delete a contact - select "Yes" on the popped-up message box - // If the message box doesn't pop up, the test fails. - expectMessageBox("Contacts", "Are you sure you want to delete: " + contact_name + "?", "Yes") { - select("Delete contact", optionsMenu()); - } - \endcode -*/ - -/*! - Indicate to the test framework if the application under test is expected to close. - - If \a value is true, the test framework will not report a failure when it loses its connection to the application. - If \a value is false, unexpected application terminations will result in a test failure. - - Example: - \code - expectApplicationClose( true ); - select( "Close" ); // Selecting this causes the current application to close - expectApplicationClose( false ); // Resume normal checking - \endcode -*/ -void QSystemTest::expectApplicationClose( bool value ) -{ - m_expect_app_close = value; -} - -/*! - \internal - Processes the command line parameters. -*/ -void QSystemTest::processCommandLine( QStringList &args ) -{ - QMutableStringListIterator it(args); - - while (it.hasNext()) { - QString arg = it.next(); - if (!arg.compare("-remote", Qt::CaseInsensitive)) { - it.remove(); - if (!it.hasNext()) qFatal("Expected a value after %s", qPrintable(arg)); - QString host_port = it.next(); - it.remove(); - QStringList host_port_parts = host_port.split(":"); - - bool ok = (host_port_parts.count() == 2); - int port = -1; - QString host; - if (ok) port = host_port_parts[1].toInt(&ok); - if (ok) host = host_port_parts[0]; - ok = ok && port > 0 && port < 65536 && !host.isEmpty(); - - if (!ok) - qFatal("'%s' is not a valid host:port argument", qPrintable(host_port)); - - QTestIDE::instance()->openRemote( host, port ); - connect(QTestIDE::instance(), SIGNAL(abort()), this, SLOT(abortTest())); - } else if ( !arg.compare("-autip", Qt::CaseInsensitive) || !arg.compare("-authost", Qt::CaseInsensitive) ) { - it.remove(); - if (!it.hasNext()) qFatal("Expected a value after %s", qPrintable(arg)); - ssh_param.host = it.next(); - it.remove(); - ssh_param.timeout = 20000; - } else if ( !arg.compare("-username", Qt::CaseInsensitive) ) { - it.remove(); - if (!it.hasNext()) qFatal("Expected a value after %s", qPrintable(arg)); - ssh_param.uname = it.next(); - it.remove(); - } else if ( !arg.compare("-pwd", Qt::CaseInsensitive) ) { - it.remove(); - if (!it.hasNext()) qFatal("Expected a value after %s", qPrintable(arg)); - ssh_param.pwd = it.next(); - it.remove(); - ssh_param.authType = Core::SshConnectionParameters::AuthByPwd; - ssh_param.privateKeyFile = ""; - } else if ( !arg.compare("-private-key", Qt::CaseInsensitive) ) { - it.remove(); - if (!it.hasNext()) qFatal("Expected a value after %s", qPrintable(arg)); - ssh_param.privateKeyFile = it.next(); - it.remove(); - ssh_param.pwd = ""; - ssh_param.authType = Core::SshConnectionParameters::AuthByKey; - } else if ( !arg.compare("-autsshport", Qt::CaseInsensitive) ) { - it.remove(); - if (!it.hasNext()) qFatal("Expected a value after %s", qPrintable(arg)); - bool ok; - ssh_param.port = it.next().toUShort( &ok ); - if (!ok) - qFatal("%s is not a valid port specifier", qPrintable(it.value())); - it.remove(); - } else if ( !arg.compare("-autport", Qt::CaseInsensitive) ) { - it.remove(); - if (!it.hasNext()) qFatal("Expected a value after %s", qPrintable(arg)); - bool ok; - m_aut_port = it.next().toUShort( &ok ); - if (!ok) - qFatal("%s is not a valid port specifier", qPrintable(it.value())); - it.remove(); - } else if ( !arg.compare("-keepaut", Qt::CaseInsensitive) ) { - it.remove(); - m_keep_aut = true; - } else if ( !arg.compare("-silentaut", Qt::CaseInsensitive) ) { - it.remove(); - m_silent_aut = true; - } else if ( !arg.compare("-noaut", Qt::CaseInsensitive) ) { - it.remove(); - m_no_aut = true; - } else if ( !arg.compare("-auto", Qt::CaseInsensitive) ) { - it.remove(); - m_auto_mode = true; - } else if ( !arg.compare("-force-manual", Qt::CaseInsensitive) ) { - it.remove(); - m_run_as_manual_test = true; - } else if ( !arg.compare("-env", Qt::CaseInsensitive) ) { - it.remove(); - if (!it.hasNext()) qFatal("Expected a value after %s", qPrintable(arg)); - m_env << it.next(); - it.remove(); - } else if ( !arg.compare("-targetid", Qt::CaseInsensitive) ) { - it.remove(); - if (!it.hasNext()) qFatal("Expected a value after %s", qPrintable(arg)); - m_targetID = it.next(); - it.remove(); - } else if ( !arg.compare("-demomode", Qt::CaseInsensitive) ) { - it.remove(); - m_demo_mode = true; - } else if ( !arg.compare("-verbose-pref", Qt::CaseInsensitive) ) { - it.remove(); - m_verbose_perf = true; - } else if ( !arg.compare("-v", Qt::CaseInsensitive) ) { - it.remove(); - m_verbose = true; - } - } - QAbstractTest::processCommandLine(args); - - if (m_auto_mode && learnMode() != LearnNone) { - qWarning("Can't learn in auto mode; learn options ignored."); - } - if (!m_auto_mode && learnMode() == LearnNone) { - setLearnMode(LearnNew); - } -} - -/*! - \internal - Starts event recording. While event recording is busy a dialog will be visible that shows all recorded events and also - enables the user to stop the recording session. \a file and \a line specifies the location in a source file where event - recording commenced. - - If \a manualSteps are specified the dialog will have an additional field showing all the manual steps. - - Don't use this, use prompt() instead. -*/ -bool QSystemTest::recordEvents( const QString &manualSteps, bool gui ) -{ - if (m_auto_mode && gui) { - skip("Can't record events in auto mode.", SkipSingle ); - return false; - } - - m_recorded_events_edit = 0; - m_recorded_code = QString(); - if (!queryPassed( "OK", "", QTestMessage("startEventRecording"))) return false; - if (gui) { - if (QTestIDE::instance()->isConnected()) { - QTestIDE::instance()->eventRecordingStarted(currentFile(), currentLine(), manualSteps); - m_recording_events = true; - while (!QTestIDE::instance()->mustStopEventRecording()) { - wait( 50 ); - } - - m_recording_events = false; - if (QTestIDE::instance()->eventRecordingAborted()) { - skip("Event recording aborted.", SkipSingle ); - } - } else { - QDialog recordWindow; - Ui::RecordDialog ui; - ui.setupUi(&recordWindow); - - if (!manualSteps.isEmpty()) { - ui.steps_view->setPlainText( manualSteps ); - } else { - ui.steps_view->hide(); - ui.steps_label->hide(); - } - - m_recorded_events_edit = ui.codeEdit; - - connect( ui.abort_button, SIGNAL(clicked()), &recordWindow, SLOT(close()) ); - connect( ui.abort_button, SIGNAL(clicked()), this, SLOT(abortPrompt()) ); - abort_prompt = false; - - m_recording_events = true; - recordWindow.exec(); - m_recording_events = false; - if (abort_prompt) { - return false; - } - - } - return queryPassed( "OK", "", QTestMessage("stopEventRecording")); - } - return true; -} - -/*! - \internal - Stops recording events, returning the generated code from event recording. - Used internally for testing event recording. -*/ -QString QSystemTest::stopRecordingEvents() -{ - queryPassed( "OK", "", QTestMessage("stopEventRecording")); - return m_recorded_code; -} - -/*! - Displays a dialog with the \a manualSteps and Pass/Fail/Record buttons, then waits for a response from - the user. - \list - \o If Pass is clicked, the test will continue. - \o If Fail is clicked, a failure will be generated and the current testcase will abort. - \o If Record is clicked, event recording will start and recorded events can be appended to the testcase - once recording is finished. - \endlist - - This function is intended to be used for verification of testcases that cannot be fully automated. - Testcases containing this function will be skipped if the test is run with the \c -auto option (i.e. - when tests are executed in a CI system). - - Example1: - \code - prompt( "Did something totally amazing just happen?" ); - \endcode - - When the test is run with \c -force-manual the \a manualSteps are accumulated and the actual prompt dialog is - not shown until the end of the test function, i.e. - \list - \o all automated commands are converted into documented manual steps - \o all \a manualSteps are added to this list - \o and the complete set of steps is shown in one go - \endlist - - For example: - \code - startApplication("foobar"); - prompt( "Do something that is difficult to automate" ); - compare( currentTitle(), "blah" ); - \endcode - - When the above example is executed in normal (automated) test execution mode 'startApplication' will - start application foobar, then show a dialog with the text "Do something that is difficult to automate" - and wait until the user clicks on Pass or Fail. If the user clicked on Fail the test will be terminated - and if the user clicked on Pass the execution will continue with the next step, i.e. an automatic - comparison of the current title against the constant 'blah'. - - If however the test is executed with \c -force-manual all text will be converted into manual steps and - nothing will be executed automatically, but instead one prompt dialog will be shown at the end of the - test function with the following steps: - \code - 1. start application 'foobar' - 2. Do something that is difficult to automate - 3. Verify that the current title is equal to 'blah' - \endcode - - \sa manualTest -*/ -void QSystemTest::prompt( const QString &manualSteps ) -{ - if (manualSteps.contains(QRegExp("<.*>.*</.*>"))) - { - // Contains HTML, don't assume it's a series of steps - showPromptDialog(manualSteps); - return; - } - - QStringList list = manualSteps.split("\n", QString::SkipEmptyParts); - foreach( QString cmd, list) - manualTest(cmd); - - if (runAsManualTest()) { - // just add the manualSteps to whatever we already have, and show prompt at the end. - return; - } - - if (m_auto_mode) { - skip("Manual test skipped", SkipSingle); - return; - } - - showPromptDialog(); -} - -/*! \internal */ -void QSystemTest::abortPrompt() -{ - abort_prompt = true; -} - -/*! - \internal - This function is called when the test IDE wants to abort the current test. -*/ -void QSystemTest::abortTest() -{ -#ifndef Q_OS_SYMBIAN - ::raise(SIGINT); -#endif -} - -//#ifndef QTCREATOR_QTEST -/*! - \internal - Print any special usage information which should be shown when test is launched - with -help. -*/ -void QSystemTest::printUsage() const -{ - QAbstractTest::printUsage(); - qWarning( - " System test options:\n" - " -authost <host> : Specify the IP address or host name of the machine on which the AUT is running.\n" - " By default, the system test will connect to %s. \n" - " -autport <port> : Use QTUITEST_DEFAULT_OPTIONS environment variable to specify autport option and value.\n" - " Specify the port on which the AUT is listening for a system test connection.\n" - " Defaults to %d. \n" - " -autsshport <port>: Specify the port to use when ssh'ing to authost.\n" - " Defaults to %d. \n" - " -username : Specify the user name when ssh'ing to authost.\n" - " -pwd : Specify the password when ssh'ing to authost.\n" - " -private-key : Specify the ssh private key when ssh'ing to authost.\n" - " -keepaut : Leave the AUT running after the system test finishes.\n" - " By default, if the system test launches the AUT, it will kill the AUT when testing\n" - " completes.\n" - " -silentaut : Hide the output of the AUT. By default, if the system test launches the AUT, the AUT's\n" - " standard output and standard error will be mixed with that of the test itself.\n" - "\n" - " -auto : Run in fully-automated mode. Any tests which require the presence of a manual\n" - " tester will be skipped.\n" - "\n" - " -force-manual : Runs all system tests as manual tests. Test cases that contain automated step are translated\n" - " into a set of documented steps.\n" - "\n" - " -verbose-perf : Output all performance messages from the AUT to the console. This may be used to run\n" - " a post-processing script on performance logs.\n" - "\n" - " -remote <host:port> : Specify the host and port of a QtUiTest-compatible test IDE, used for manual\n" - " verification steps. The default is to not use an IDE.\n" - " -env VAR=VALUE : Specify additional environment variables to be applied to tested \n" - " applications. For example, pass -env DISPLAY=:123 to run tested \n" - " applications on a different X server.\n" - " -targetID : Specify the target identifier for system under test, defaults to \'default\' or $QTUITEST_TARGETID if set\n" - , DEFAULT_AUT_HOST, DEFAULT_AUTSSH_PORT, DEFAULT_AUT_PORT - ); -} -//#endif - -#ifndef Q_QDOC -/* - Fail returning a bool is for internal use only. - Hide from documentation. -*/ -/*! - \internal - Cause a test failure with the given \a message. - Returns true if the test should continue (e.g., because the failure was expected), false otherwise. -*/ -bool QSystemTest::fail(QString const &message) -{ - if (m_expect_app_close && - (message.startsWith("ERROR: Connection lost") || - message.startsWith("ERROR: no data in reply to") || - message.startsWith("reply was missing return value") || - message.startsWith("ERROR_NO_CONNECTION")) ) { - return true; - } - - static bool saving_screen = false; - static bool saving_info = false; - static QString saving_screen_failed; - static QString saving_info_failed; - /* Prevent recursive failure on saving screen/widget info */ - if (saving_screen) { - saving_screen_failed = "Failed to save failure screenshot: " + message; - return true; - } - if (saving_info) { - saving_info_failed = "Failed to save widget info on failure: " + message; - return true; - } - - bool ret = QTest::compare_helper( false, qPrintable(message), qPrintable(currentFile()), currentLine() ); - if (!ret) { - saving_screen = true; - saving_screen_failed = QString(); - - QString config = configurationIdentifier(); - saveScreen("failure_" + config); - - saving_screen = false; - - if (saving_screen_failed.isEmpty()) { - // If we saved it, let the IDE know. - QFileInfo info(currentDataPath() + "/failure_" + config + ".png"); - if (info.exists()) { - QTestIDE::instance()->failureScreenshot(info.canonicalFilePath(), currentFile(), currentLine(), QTest::currentTestFunction()); - } - } - - saving_info = true; - saving_info_failed = QString(); - - QString info = activeWidgetInfo(); - - saving_info = false; - if (!info.isEmpty()) { - QFile f(currentDataPath() + "/failure_" + config + ".txt"); - if (!f.exists() && f.open(QIODevice::WriteOnly)) { - QTextStream(&f) - << message << "\n" - << "Location: " << currentFile() << ":" << currentLine() << "\n" - << (saving_screen_failed.isEmpty() - ? "Also see failure_" + config + ".png for a screenshot." - : saving_screen_failed) - << "\n" - << (saving_info_failed.isEmpty() - ? info - : saving_info_failed) - << "\n"; - } - } - } - return ret; -} -#endif - -/*! - - Cause a test to skip with the given \a message and \a mode. - -*/ -void QSystemTest::skip(const QString& message, SkipMode mode) -{ - m_skip_current_function = true; - - // If there is no test data for this function, always use - // SkipAll to avoid reporting both SKIP and PASS result - if (currentDataTag().isEmpty()) - mode = SkipAll; - - QTest::qSkip(qPrintable(message), QTest::SkipMode(mode), qPrintable(currentFile()), currentLine()); -} - -/*! - \internal - Returns true if the last executed query has failed. - If \a message is not null, a failure message is returned in \a message. - If \a sent is not null, the message sent from the system test which - caused the failure is returned in \a sent. -*/ -bool QSystemTest::queryFailed( QTestMessage *message, QTestMessage *sent ) -{ - if (message != 0) - *message = m_error_msg; - if (sent != 0) - *sent = m_error_msg_sent; - return query_failed; -} - -/*! - \internal - Informs the testframework that error situations need to be reported as warnings. -*/ -void QSystemTest::enableQueryWarnings( bool enable, const QString &file, int line ) -{ - setLocation( file, line ); - - if (!enable) { - m_error_msg = QTestMessage(); - query_failed = false; - } - query_warning_mode = enable; -} - -/*! - \internal - Saves the \a file and \a line information for internal usage. Whenever an error situation occurs this data is appended to the error message to improve traceability of the error. - - It is usually not necessery to call this function directly. -*/ -void QSystemTest::setLocation( const QString &file, int line ) -{ - m_loc_fname = file; - m_loc_line = line; -} - -/*! - \internal - Returns the current filename, i.e. the file that was being executed when the error situation occurred. -*/ -QString QSystemTest::currentFile() -{ - return m_loc_fname; -} - -/*! - \internal - Returns the current line number, i.e. the line number that presumably caused the error situation. -*/ -int QSystemTest::currentLine() -{ - return m_loc_line; -} - -/*! - \internal - Saves the error string \a errString for future processing. If warning mode is enabled the error is written directly to std out as a warning. - Base implementation returns false; subclasses may return true to indicate that the error is not considered "fatal". -*/ -bool QSystemTest::setQueryError( const QString &errString ) -{ - query_failed = true; - m_error_msg["status"] = errString; - m_error_msg_sent = m_last_msg_sent; - if (query_warning_mode) - qWarning( errString.toLatin1() ); - return false; // query is NOT successfull -} - -/*! - \internal - Saves the error specified in the test \a message for future processing. If warning mode is enabled the error is written directly to std out as a warning. - Base implementation returns false; subclasses may return true to indicate that the error is not considered "fatal". -*/ -bool QSystemTest::setQueryError( const QTestMessage &message ) -{ - query_failed = true; - m_error_msg = message; - m_error_msg_sent = m_last_msg_sent; - if (query_warning_mode) - qWarning( QString("%1 %2").arg(message.event()).arg(message.toString()).toLatin1().constData() ); - return false; // query is NOT successfull -} - -//#ifndef QTCREATOR_QTEST -/*! - \internal - Launch AUT and run the test. -*/ -int QSystemTest::runTest(const QString &fname, const QStringList &args, - const QStringList &environment) -{ - // Try to launch the aut script, and if successful, start executing the test. - // QTest::qExec will also start the application event loop, and will not return until the tests have finished. - - return QAbstractTest::runTest(fname, args, environment); -} -//#endif - -/*! - \internal - Attempts to launch the AUT (Application Under Test), and returns whether it was successful. - The \c -remote command line argument is appended to the script with the IP set to the address of the - local machine. This is to allow the test system to connect to the machine the test is running on. - - Any scripts used should support this. -*/ -bool QSystemTest::connectToAut(int timeout) -{ - if (!m_test_app) - m_test_app = new QSystemTestMaster( this ); - - QTime t; - t.start(); - while (t.elapsed() < timeout && !isConnected()) { - m_test_app->connect( ssh_param.host, m_aut_port ); - m_test_app->waitForConnected(2000); - } - - if (!m_test_app->isConnected()) { - qLog(QtUitest) << qPrintable(QString("'%1' while trying to connect to test app on %2:%3. ").arg(m_test_app->errorStr()).arg(ssh_param.host).arg(m_aut_port)) ; - return false; - } - - // Don't try to reconnect if connection is lost ... it's pointless - m_test_app->enableReconnect(false, 0); - - if (m_demo_mode) setDemoMode(true); - - return true; -} - -/*! - \internal -*/ -void QSystemTest::disconnectFromAut() -{ - m_test_app->disconnect(); -} - -/*! - Returns the username that is running the test on the desktop machine. -*/ -QString QSystemTest::userName() -{ - QString user_name; - -#if defined Q_OS_TEMP - user_name = "WinCE"; -#elif defined Q_OS_WIN32 - user_name = ::getenv("USERNAME"); -#elif defined Q_OS_UNIX - user_name = ::getenv("USER"); - if (user_name == "") - user_name = ::getenv( "LOGNAME" ); -#elif defined Q_OS_MAC - user_name = ::getenv(); -#endif - - return user_name.toLower(); -} - -/*! - Runs \a application with arguments \a args on the local machine, - with \a input given as standard input. The combined stderr and stdout text will be returned. - - If the process fails to run or returns a non-zero exit code, the current test fails. -*/ -QString QSystemTest::runProcess( const QString &application, const QStringList &args, const QString &input ) -{ - QString output; - QProcess p; - p.setReadChannelMode(QProcess::MergedChannels); - p.setReadChannel(QProcess::StandardOutput); - p.start(application, args); - if (p.waitForStarted()) { - if (!input.isEmpty()) { - p.write( input.toLatin1() ); - } - p.closeWriteChannel(); - while (p.state() == QProcess::Running) { - while (p.canReadLine()) { - output += p.readLine(); - } - wait(10); //important - } - while (p.canReadLine()) { - output += p.readLine(); - } - if (p.exitStatus() != QProcess::NormalExit) { - setQueryError("Process didn't exit normally\n" + output); - return QString(); - } - int ec = p.exitCode(); - if (0 != ec) { - QString err_str = QString("Process exited with exit code: %1\n%2").arg(ec).arg(output); - setQueryError(err_str); - return QString(); - } - return output; - } - setQueryError("Process didn't start"); - return output; -} - -/****************************************************************************** -* DOCUMENTATION FOR FUNCTIONS IN builtins.js -******************************************************************************/ - -/*! - Compares the \a actual string with the \a expected string and reports a fail - with a nicely formatted error message in case the strings are not equal. - - Example: - \code - var my_variable1 = "Test"; - var my_variable2 = "Test2"; - compare( my_variable1, "Test" ); // passes - compare( my_variable2, "Test" ); // will fail the test, and test execution will stop at this line - \endcode - - \sa verify() -*/ -#ifdef Q_QDOC -void QSystemTest::compare( const QString &actual, const QString &expected ) -{ - // This code is implemented in the QtUiTestrunner bindings -} -#endif - -/*! - Aborts the test with a failure message if \a statement is false. - The failure messages returned by compare() are generally speaking better readable (more informative) and is preferred when working with strings. - - Example: - \code - var my_variable1 = "Test"; - var my_variable2 = "Test2"; - verify( my_variable1 == "Test" ); // passes - verify( my_variable2 == "Test" ); // will fail the test, and test execution will stop at this line - \endcode - - \sa compare() -*/ -#ifdef Q_QDOC -void QSystemTest::verify( bool statement ) -{ - // This code is implemented in the QtUiTestrunner bindings -} -#endif - -/*! - \fn QSystemTest::waitFor(Number timeout, Number intervals, String message) - - Denotes the start of a block of code which should be repeatedly executed - until it returns true. If the block of code doesn't return true within - \a timeout milliseconds, the current test fails with the given \a message. - - \a intervals is the maximum amount of times the block of code should be - executed; i.e., the code will be executed every \a timeout / \a intervals - milliseconds. - - Example: - \code - waitFor() { - return getList().length > 0; - } - \endcode -*/ - - -/*! - \fn QSystemTest::verify(Boolean condition, String message) - - Verifies that \a condition is true. If \a condition is not true, the - current test fails. If \a message is given, it will be appended to - the failure message. - - Example: - \code - select("Frank", "Contacts"); - waitForTitle("Details: Frank"); - var details = getText(); - // Verify that Frank's phone number is shown somewhere - verify( details.contains("12345") ); - // Same, but with more details in error message - verify( details.contains("12345"), "Frank's phone number is missing!" ); - \endcode -*/ - -/*! - \fn QSystemTest::compare(Variant actual, Variant expected) - - Verifies that \a actual is equal to \a expected. If this is not the case, - the current test fails. - - Note that the order of \a actual and \a expected is significant, as it - affects the test failure message. -*/ - -/*! - \fn QSystemTest::fail(String message) - - Immediately fail the current test with the specified \a message. -*/ - -/*! - Returns the signature of the tabbar widget. If multiple tabbars exist, \a index can be used to - distinguish between them (sorted in order of position from top left of screen). - - Example: - \code - select( "Personal", tabBar() ); // select the tab with text 'Personal' from the tab bar. - print( tabBar() ); // to print the signature of the tabbar widget. - \endcode - - The test will fail if no visible tabbar is found. -*/ -#ifdef Q_QDOC -void QSystemTest::tabBar( int index ) -{ - // This code is implemented in the QtUiTestrunner bindings -} -#endif - -/*! - \internal - Returns an identifier for the current runtime configuration. - Includes mousePreferred(), screen size and theme. -*/ -QString QSystemTest::configurationIdentifier() const -{ - return m_config_id; -} - -/*! - \internal -*/ -void QSystemTest::setConfigurationIdentifier(QString const& config) -{ - m_config_id = config; -} - -/*! - \internal -*/ -bool QSystemTest::verbose() const -{ - return m_verbose; -} - -/*! - \internal -*/ -bool QSystemTest::doQuery(const QTestMessage& message, const QString& queryPath, QTestMessage* reply, int timeout, const QStringList& pass, const QStringList& fail) -{ return queryPassed(pass, fail, message, queryPath, reply, timeout); } - -/*! - \internal - Prints \a value. -*/ -void QSystemTest::print( QVariant const& value ) -{ - QDebug(QtDebugMsg) << qPrintable(value.toString()); -} - -/*! \internal - Enables/disables waits and animations for demo purposes. -*/ -void QSystemTest::setDemoMode( bool enabled ) -{ - QTestMessage queryMsg("enableDemoMode"); - queryMsg["enable"] = enabled; - queryPassed( "OK", "", queryMsg ); -} - -/*! - \internal -*/ -bool QSystemTest::demoMode() const -{ - return m_demo_mode; -} - -/*! - \internal -*/ -QString QSystemTest::autHost() const -{ - return ssh_param.host; -} - -/*! - \internal -*/ -int QSystemTest::autPort() const -{ - return m_aut_port; -} - -/*! - Uses the \a reason to mark the current testfunction as expected to fail. -*/ -void QSystemTest::expectFail( const QString &reason ) -{ - QEXPECT_FAIL(currentDataTag().toLatin1().constData(), qstrdup(reason.toLatin1().constData()), Abort); -} - -/*! - Returns the translation for \a text, from the application's installed translation files. \a context is - typically a class name. If no translation is found, the \a text is returned unchanged. - - \a comment is a disambiguating comment, for when the same sourceText is used in different roles - within the same context. By default, it is null. \a n is used in conjunction with \c %n to support - plural forms. See QObject::tr() for details. - - When developing test cases that use translations, it will be necessary to refer to the translator - message files (\c .ts files), either directly or through Qt Linguist, to determine which - translations are available, and the appropriate \a context to use. - - In some cases, translated phrases will contain argument placeholders (\c %1, etc) which will need - to be expanded with the correct values. - - Example: - \code - // Label translation - print( translate("QFileDialog", "File &name:") ); - - // Replace argument placeholders - compare( message, translate("QHttp", "Host %1 not found").replace("%1", hostname) ); - \endcode - - \sa QCoreApplication::translate(), getLocale() -*/ -QString QSystemTest::translate(const QString &context, const QString &text, const QString &comment, int n) -{ - QTestMessage message("translate"); - message["context"] = context; - message["text"] = text; - message["comment"] = comment; - message["number"] = n; - QTestMessage reply; - - if (!queryPassed( "OK", "", BT(message), "", &reply )) return false; - return reply["translate"].toString(); -} - -/*! - Returns the system locale. - - \sa QLocale::system(), translate() -*/ -QLocale QSystemTest::getLocale() -{ - QTestMessage message("getLocale"); - QTestMessage reply; - - if (!queryPassed( "OK", "", BT(message), "", &reply )) return QLocale(); - return reply["getLocale"].toLocale(); -} - -/*! - \internal -*/ -void QSystemTest::qtuitest_pre_test_function() -{ - m_query_count = 0; - m_skip_current_function = false; -} - -/*! - \internal -*/ -void QSystemTest::qtuitest_post_test_function() -{ - if (!m_manual_commands.isEmpty() && !QTest::currentTestFailed()) { - showPromptDialog(); - } - - if (failEmptyTest() && m_query_count == 0 && !m_skip_current_function && !QTest::currentTestFailed()) { - fail("Nothing tested"); - } -} - -/*! - \internal -*/ -bool QSystemTest::runAsManualTest(void) -{ - return m_run_as_manual_test; -} - -/*! - \internal - Pass any configuration values to the system under test - */ -void QSystemTest::configTarget() -{ - if (m_run_as_manual_test) - return; - - // set the target identifier - if (!m_targetID.isEmpty()) - setTargetIdentifier(m_targetID); -} - -/*! \typedef StringArray - \relates QSystemTest - - An \l Array object in which every element is a \l String. -*/ - -/*! \typedef QVariantArray - \relates QSystemTest - - An \l Array object in which every element is a \l QVariant. -*/ - -/*! \typedef Function - \relates QSystemTest - - The Function type as documented in ECMA-262, section 15.3. -*/ - -/*! \typedef Array - \relates QSystemTest - - The Array type as documented in ECMA-262, section 15.4. - - The following extensions are provided in QtUiTest. - - \table - \row \o \tt{\l Boolean Array.prototype.contains(value)} - \o Returns true if the array contains the given value. - \endtable -*/ - -/*! \typedef String - \relates QSystemTest - - The String type as documented in ECMA-262, section 15.5. - - The following extensions are provided in QtUiTest. - - \table - \row \o \tt{ \l Boolean String.prototype.contains(String text)} - \o Returns true if the string contains the given text. - \row \o \tt{ \l Boolean String.prototype.contains(\l QRegExp regex)} - \o Returns true if the string is matched by the given regular expression. - \row \o \tt{ \l Boolean String.prototype.startsWith(String text)} - \o Returns true if the string starts with the given text. - \row \o \tt{ String String.prototype.left(\l Number n)} - \o Returns the first n characters of the string. - \row \o \tt{ String String.prototype.right(\l Number n)} - \o Returns the last n characters of the string. - \endtable -*/ - - -/*! \typedef Boolean - \relates QSystemTest - - The Boolean type as documented in ECMA-262, section 15.6. -*/ - -/*! \typedef Number - \relates QSystemTest - - The Number type as documented in ECMA-262, section 15.7. -*/ diff --git a/libqsystemtest/qsystemtest.h b/libqsystemtest/qsystemtest.h deleted file mode 100644 index fcfa3f5..0000000 --- a/libqsystemtest/qsystemtest.h +++ /dev/null @@ -1,582 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of QtUiTest. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QSYSTEMTEST_H -#define QSYSTEMTEST_H - -#include "qabstracttest.h" -#include "qtestprotocol_p.h" -#include "recordevent_p.h" -#include <testcontrol.h> - -#include <QStringList> -#include <QDir> -#include <QLocale> -#include <QPointer> - -class QProcess; -class QSystemTestMail; -class QSystemTestMaster; -class QTextEdit; - -#define DEFAULT_QUERY_TIMEOUT 120000 - -class QTestMessage; - -#ifdef Q_QDOC -namespace QSystemTest -#else -class QSYSTEMTEST_EXPORT QSystemTest : public QAbstractTest -#endif -{ -Q_OBJECT -Q_ENUMS(SkipMode) -Q_ENUMS(EnterMode) -Q_ENUMS(LabelOrientation) -Q_ENUMS(StartApplicationFlag) -Q_FLAGS(StartApplicationFlags) -Q_ENUMS(Role) -Q_ENUMS(StateFlag) -Q_FLAGS(State) - -public: - QSystemTest(); - virtual ~QSystemTest(); - - enum SkipMode - { - SkipSingle = 0x01, - SkipAll = 0x02 - }; - - enum EnterMode - { - Commit = 0x00, - NoCommit = 0x01 - }; - - enum LabelOrientation - { - LabelLeft = 0x01, - LabelRight = 0x02, - LabelAbove = 0x03, - LabelBelow = 0x04 - }; - - enum StartApplicationFlag - { - NoFlag = 0x00, - WaitForFocus = 0x01, - BackgroundCurrentApplication = 0x02 - }; - Q_DECLARE_FLAGS(StartApplicationFlags, StartApplicationFlag) - - // This should match QAccessible::Role - enum Role { - NoRole = 0x00000000, - TitleBar = 0x00000001, - MenuBar = 0x00000002, - ScrollBar = 0x00000003, - Grip = 0x00000004, - Sound = 0x00000005, - Cursor = 0x00000006, - Caret = 0x00000007, - AlertMessage = 0x00000008, - Window = 0x00000009, - Client = 0x0000000A, - PopupMenu = 0x0000000B, - MenuItem = 0x0000000C, - ToolTip = 0x0000000D, - Application = 0x0000000E, - Document = 0x0000000F, - Pane = 0x00000010, - Chart = 0x00000011, - Dialog = 0x00000012, - Border = 0x00000013, - Grouping = 0x00000014, - Separator = 0x00000015, - ToolBar = 0x00000016, - StatusBar = 0x00000017, - Table = 0x00000018, - ColumnHeader = 0x00000019, - RowHeader = 0x0000001A, - Column = 0x0000001B, - Row = 0x0000001C, - Cell = 0x0000001D, - Link = 0x0000001E, - HelpBalloon = 0x0000001F, - Assistant = 0x00000020, - List = 0x00000021, - ListItem = 0x00000022, - Tree = 0x00000023, - TreeItem = 0x00000024, - PageTab = 0x00000025, - PropertyPage = 0x00000026, - Indicator = 0x00000027, - Graphic = 0x00000028, - StaticText = 0x00000029, - EditableText = 0x0000002A, - PushButton = 0x0000002B, - CheckBox = 0x0000002C, - RadioButton = 0x0000002D, - ComboBox = 0x0000002E, - ProgressBar = 0x00000030, - Dial = 0x00000031, - HotkeyField = 0x00000032, - Slider = 0x00000033, - SpinBox = 0x00000034, - Canvas = 0x00000035, - Animation = 0x00000036, - Equation = 0x00000037, - ButtonDropDown = 0x00000038, - ButtonMenu = 0x00000039, - ButtonDropGrid = 0x0000003A, - Whitespace = 0x0000003B, - PageTabList = 0x0000003C, - Clock = 0x0000003D, - Splitter = 0x0000003E, - LayeredPane = 0x0000003F, - UserRole = 0x0000ffff - }; - - // This should match QAccessible::StateFlag - enum StateFlag { - Normal = 0x00000000, - Unavailable = 0x00000001, - Selected = 0x00000002, - Focused = 0x00000004, - Pressed = 0x00000008, - Checked = 0x00000010, - Mixed = 0x00000020, - ReadOnly = 0x00000040, - HotTracked = 0x00000080, - DefaultButton = 0x00000100, - Expanded = 0x00000200, - Collapsed = 0x00000400, - Busy = 0x00000800, - Marqueed = 0x00002000, - Animated = 0x00004000, - Invisible = 0x00008000, - Offscreen = 0x00010000, - Sizeable = 0x00020000, - Movable = 0x00040000, - SelfVoicing = 0x00080000, - Focusable = 0x00100000, - Selectable = 0x00200000, - Linked = 0x00400000, - Traversed = 0x00800000, - MultiSelectable = 0x01000000, - ExtSelectable = 0x02000000, - Protected = 0x20000000, - HasPopup = 0x40000000, - Modal = 0x80000000 - }; - Q_DECLARE_FLAGS(State, StateFlag) - -public slots: - virtual bool runAsManualTest(void); - virtual void manualTest( const QString &description ); - virtual void manualTestData( const QString &description, bool isAlternative = false ); - - void prompt(const QString& = QString()); - - // commands to control test execution - void strict( bool = true ); - void setDemoMode( bool ); - static QString userName(); - bool shouldFilterMessage(char const*); - QMap<QString, int> filteredMessages() const; - void clearFilteredMessages(); - bool runsOnDevice(); - - virtual void skip(const QString&, SkipMode); - virtual void expectFail(const QString&); - - QString signature(const QString&, int = 0); - - // widget checks - bool isVisible(const QString&); - bool isEnabled(const QString&); - - // checkBox manipulators - bool isChecked(const QString&); - bool isChecked(const QString&, const QString&); - void setChecked(bool,const QString& = QString()); - void setChecked(bool,const QString&,const QString&); - int checkState(const QString&); - void setCheckState(int,const QString& = QString()); - - // data verification functions - QString currentApplication(); - QString applicationVersion(); - QString qtVersion(); - QString currentTitle(const QString& = QString()); - QStringList getWindowTitles(); - void activateWindow(const QString&); - QString activeWindow(); - QString focusWidget(); - QString getSelectedText(const QString& = QString() ); - QString getText(const QString& = QString() ); - QVariant getSelectedValue(const QString& = QString() ); - QVariant getValue(const QString& = QString() ); - QStringList getList(const QString& = QString() ); - QPoint getCenter(const QString&, const QString&); - QStringList getLabels(const QString& = QString() ); - - // clipboard - QString getClipboardText(); - void setClipboardText(const QString&); - - // time management functions - QDateTime getDateTime(); - - int visibleResponseTime(); - void setVisibleResponseTime(int); - - // application management functions - virtual void startApplication(const QString&, const QStringList& = QStringList(), int timeout = 5000, - QSystemTest::StartApplicationFlags = QSystemTest::WaitForFocus); - virtual void killApplication(); - void expectApplicationClose(bool); - - // low level simulators - void keyClick(Qt::Key,const QString& = QString()); - void keyClickHold(Qt::Key,int,const QString& = QString()); - void keyPress(Qt::Key,const QString& = QString()); - void keyRelease(Qt::Key,const QString& = QString()); - - void mouseClick(int,int,QFlags<Qt::MouseButton> = Qt::LeftButton); - void mouseClick(const QPoint&,QFlags<Qt::MouseButton> = Qt::LeftButton); - void mouseClick(const QString&,QFlags<Qt::MouseButton> = Qt::LeftButton); - void mouseClickHold(int,int,int,QFlags<Qt::MouseButton> = Qt::LeftButton); - void mouseClickHold(const QPoint&,int,QFlags<Qt::MouseButton> = Qt::LeftButton); - void mouseClickHold(const QString&,int,QFlags<Qt::MouseButton> = Qt::LeftButton); - void mousePress(int,int,QFlags<Qt::MouseButton> = Qt::LeftButton); - void mousePress(const QPoint&,QFlags<Qt::MouseButton> = Qt::LeftButton); - void mousePress(const QString&,QFlags<Qt::MouseButton> = Qt::LeftButton); - void mouseRelease(int,int,QFlags<Qt::MouseButton> = Qt::LeftButton); - void mouseRelease(const QPoint&,QFlags<Qt::MouseButton> = Qt::LeftButton); - void mouseRelease(const QString&,QFlags<Qt::MouseButton> = Qt::LeftButton); - - bool mousePreferred(); - void setMousePreferred(bool); - - LabelOrientation labelOrientation(); - void setLabelOrientation(LabelOrientation); - - // input and selection functions - void enter(const QVariant&,const QString& = QString(),EnterMode = Commit); - void select(const QString&,const QString& = QString()); - void selectIndex(const QVariantList&,const QString& = QString()); - QVariantList getSelectedIndex(const QString& = QString()); - void activate(const QString&); - void ensureVisible(const QString&,const QString& = QString()); - - // verification mechanisms - void verifyImage(const QString&,const QString& = QString(), - const QString& = QString(),const QStringList& = QStringList()); - bool compareImage( const QString&, const QString&, const QStringList& = QStringList()); - bool recordEvents(const QString&, bool = true); - QString stopRecordingEvents(); - - // testcase synchronisation - void wait(int); - - // graphical manipulation - void saveScreen(const QString&, const QString& = ""); - QImage grabImage(const QString& = QString(),const QStringList& = QStringList()); - - // environment manipulation functions - QString runProcess(const QString&,const QStringList&,const QString&); - QString getenv(const QString&); - bool checkOS(const QString&); - QString targetIdentifier(); - void setTargetIdentifier(const QString &); - void putFile(const QString&,const QString&,QFile::Permissions=0); - void putData(const QByteArray&,const QString&,QFile::Permissions=0); - void getFile(const QString&,const QString&); - QString readLocalFile(const QString&); - QString getData(const QString&); - void deletePath(const QString&); - QStringList getDirectoryEntries(const QString&,QDir::Filters = QDir::NoFilter); - - QSize getImageSize(const QString&); - QRect getGeometry(const QString& = QString()); - - void setProperty(const QString&,const QString&,const QVariant&); - QVariant getProperty(const QString&,const QString&); - QStringList findByProperty(const QString&, const QVariant&); - QStringList findByProperty(const QVariantMap&); - QStringList findWidget(const QString&, const QVariant&); - QStringList findWidget(const QVariantMap&); - - bool invokeMethod(const QString&,const QString&, - const QVariant& = QVariant(),const QVariant& = QVariant(),const QVariant& = QVariant(), - const QVariant& = QVariant(),const QVariant& = QVariant(),const QVariant& = QVariant(), - const QVariant& = QVariant(),const QVariant& = QVariant(),const QVariant& = QVariant(), - const QVariant& = QVariant()); - - bool invokeMethod(const QString&,const QString&,Qt::ConnectionType, - const QVariant& = QVariant(),const QVariant& = QVariant(),const QVariant& = QVariant(), - const QVariant& = QVariant(),const QVariant& = QVariant(),const QVariant& = QVariant(), - const QVariant& = QVariant(),const QVariant& = QVariant(),const QVariant& = QVariant(), - const QVariant& = QVariant()); - - QVariant getSetting(const QString&,const QString&,const QString&); - QVariant getSetting(const QString&,const QString&,const QString&,const QString&); - void setSetting(const QString&,const QString&,const QString&,const QVariant&); - void setSetting(const QString&,const QString&,const QString&,const QString&,const QVariant&); - QString translate(const QString&, const QString&, const QString& = QString(), int = 0); - QLocale getLocale(); - - // debug helper functions - QString activeWidgetInfo(); - - void print(QVariant const&); - - void qtuitest_pre_test_function(); - void qtuitest_post_test_function(); - - // These public slots come from QSystemTestPrivate - QTestMessage query( const QTestMessage &message, const QString &queryPath = QString(), - int timeout = DEFAULT_QUERY_TIMEOUT ); - bool queryPassed( const QStringList &passResult, const QStringList &failResult, - const QTestMessage &message, const QString &queryPath = QString(), - QTestMessage *reply = 0, int timeout = DEFAULT_QUERY_TIMEOUT ); - bool queryPassed( const QString &passResult, const QString &failResult, - const QTestMessage &message, const QString &queryPath = QString(), - QTestMessage *reply = 0, int timeout = DEFAULT_QUERY_TIMEOUT ); - void recordPrompt(); - bool recentEventRecorded(); - void resetEventTimer(); - -public: - void setConnectionParameters( Qt4Test::TestController::TestDeviceType &type, - Core::SshConnectionParameters param ); - virtual void applicationStandardOutput(QList<QByteArray> const&); - virtual void applicationStandardError(QList<QByteArray> const&); - -protected slots: - void abortPrompt(); - void abortTest(); - -protected: - virtual void printUsage() const; - virtual int runTest(const QString &fname, const QStringList ¶meters, - const QStringList &environment); - virtual void processCommandLine(QStringList&); - - bool connectToAut(int timeout = 10000); - void disconnectFromAut(); - bool isConnected() const; - bool demoMode() const; - QString autHost() const; - void configTarget(); - - int autPort() const; - - virtual QString currentFile(); - virtual int currentLine(); - - QString configurationIdentifier() const; - void setConfigurationIdentifier(QString const&); - - bool verbose() const; - -#ifndef Q_QDOC - virtual bool fail(QString const&); - bool doQuery(const QTestMessage& message, const QString& queryPath = QString(), QTestMessage* reply = 0, int timeout = DEFAULT_QUERY_TIMEOUT, const QStringList& pass = QStringList("OK"), const QStringList& fail = QStringList()); - inline bool doQuery(const QTestMessage& message, const QString& queryPath, QTestMessage* reply, int timeout, const QString& pass, const QString& fail = QString()) - { return doQuery(message,queryPath,reply,timeout,QStringList(pass),QStringList(fail)); } - - template <typename T> inline - T queryWithReturn(T const& ret, QString const& msg, QString const& queryPath) - { - QTestMessage reply; - QTestMessage testMessage(msg); - if (!doQuery(testMessage, queryPath, &reply)) return ret; - if (!reply[msg].isValid()) { - reply["status"] = QString("ERROR: no data in reply to %1; status: %2").arg(msg).arg(reply["status"].toString()); - setQueryError(reply); - return ret; - } - return reply[msg].value<T>(); - } -#endif - - virtual bool setQueryError(const QTestMessage&); - virtual bool setQueryError(const QString&); - - virtual bool queryFailed(QTestMessage* = 0,QTestMessage* = 0); - virtual void enableQueryWarnings(bool,const QString& = QString(),int = -1); - virtual void setLocation(const QString& = QString(),int = -1); - - virtual void processMessage(const QTestMessage&); - - bool abort_prompt; - -public: -// public functions imported from QSystemTestPrivate - void recordedEvent( const QTestMessage &msg ); - void recordEvents( QList<RecordEvent> const& ); - void parseKeyEventToCode( const QTestMessage &msg); - - QVariant getSetting(const QString&,const QString&,const QString&,const QString&,const QString&); - void setSetting(const QString&,const QString&,const QString&,const QString&,const QString&,const QVariant&); - - bool imagesAreEqual( const QImage &actual, const QImage &expected, bool strict = false ); - bool learnImage( const QImage &actual, const QImage &expected, const QString &comment = QString()); - - QString processEnvironment( QString const& ) const; - QStringList processEnvironment( QStringList const& ) const; - QString PATH(); - QString which( const QString &appName ); - -signals: - void appGainedFocus(QString const &appName); - void appBecameIdle(QString const &appName); - -protected: - QStringList m_env; - -private: - friend class QSystemTestMaster; - friend class QSystemTestPrivate; - friend class QSystemTestMail; - friend class TestProcess; - - QMap<QString, int> m_filteredMessages; - QTime *event_timer; - QTime key_hold_started; - QSystemTestMaster *m_test_app; - QTestMessage m_error_msg; - QTestMessage m_error_msg_sent; - QTestMessage m_last_msg_sent; - - QTimer *key_enter_timer; - - QPointer<QTextEdit> m_recorded_events_edit; - - bool recorded_events_as_code; - bool record_prompt; - bool query_failed; - bool query_warning_mode; - int fatal_timeouts; - int timeouts; - - Qt::Key m_keyclickhold_key; - QString m_keyclickhold_path; - QString current_application; - QString current_app_version; - - QString m_loc_fname; - int m_loc_line; - - class ExpectedMessageBox { - public: - QString test_function; - QString data_tag; - QString title; - QString text; - QString option; - }; - QList<ExpectedMessageBox*> expected_msg_boxes; - - bool m_auto_mode; - bool m_run_as_manual_test; - QString m_manual_commands; - QStringList m_manual_command_data; - QStringList alternative_command_data; - void showPromptDialog(const QString& = QString()); - bool isConnected(); - - // the following parameters are used to start an Application_Under_Test - Qt4Test::TestController *device_controller; - Core::SshConnectionParameters ssh_param; - quint16 m_aut_port; - bool m_keep_aut; - bool m_silent_aut; - bool m_no_aut; - bool m_demo_mode; - bool m_verbose_perf; - bool m_verbose; - QString m_targetID; - QMap<QString, QString> appNameToBinary; - bool m_strict_mode; - int m_visible_response_time; - QList<RecordEvent> recorded_events; - QString m_recorded_code; - int display_id; - QString device; - bool m_mousePreferred; - QRect screenGeometry; - QString theme; - QString m_config_id; - bool m_recording_events; - bool m_expect_app_close; - int m_query_count; - bool m_skip_current_function; - -#ifdef Q_QDOC -/* Functions where implementation is in QtScript */ -public: - void waitFor(Number = 10000,Number = 20,String = null); - void expectMessageBox(String,String,String,Number); - void compare(Variant,Variant); - void verify(Boolean,String = null); - void fail(String); - void tabBar(int = 0); -#endif -}; - -Q_DECLARE_OPERATORS_FOR_FLAGS(QSystemTest::StartApplicationFlags) - -#ifdef Q_QDOC -typedef Nothing String; -typedef Nothing StringArray; -typedef Nothing QVariantArray; -typedef Nothing Boolean; -typedef Nothing Number; -typedef Nothing Array; -typedef Nothing Function; -#endif - -#endif diff --git a/libqsystemtest/qsystemtest_p.cpp b/libqsystemtest/qsystemtest_p.cpp deleted file mode 100644 index dd0600c..0000000 --- a/libqsystemtest/qsystemtest_p.cpp +++ /dev/null @@ -1,909 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of QtUiTest. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <qsystemtest.h> -#include "qsystemtestmaster_p.h" -#include "qtestverifydlg_p.h" -#include "qtestide.h" -#include "recordevent_p.h" -#include "qtuitest_config.h" -#include "ui_manualverificationdlg.h" -#include "ui_failuredlg.h" -#include "ui_recorddlg.h" - -#include <QProcess> -#include <QTextEdit> -#include <QMessageBox> -#include <QMetaEnum> - - -#undef qLog -#define qLog(A) if (!m_verbose); else (QDebug(QtDebugMsg) << #A ":") - -#define OBJECT_EXIST_TIMEOUT 1000 - -#define BT(message) (\ - message["location"] = QString("%1:%2%3").arg(__FILE__).arg(__LINE__).arg(!message["location"].toString().isEmpty() ? QString("\n") + message["location"].toString() : QString()),\ - message) - -/*! - \internal - Determines whether to learn the new pixmap by displaying a prompt to the user. - \a actual is the current snapshot, while \a expected is the stored pixmap (if any). - If the user does not accept the new snapshot, a failure is generated for \a file at \a line, and - \c false is returned. Otherwise the new snapshot replaces the previous stored one, and \c true is returned. - \a comment is a comment intended to help the user decide whether or not to accept the pixmap. - - If this is a GUI application, the prompt is displayed directly. Otherwise it sends a message to - any connected IDE's to display the message. -*/ -bool QSystemTest::learnImage(const QImage &actual, const QImage &expected, const QString &comment) -{ - if (QTestIDE::instance()->isConnected()) { - return QTestIDE::instance()->verifyImage(actual.isNull() ? QPixmap() : QPixmap::fromImage(actual), - expected.isNull() ? QPixmap() : QPixmap::fromImage(expected), - comment); - } else { - QTestVerifyDlg dlg; - dlg.setWindowFlags(dlg.windowFlags() | Qt::WindowStaysOnTopHint); - QString fullComment("Does the 'Actual' image show the correct output?\n" + comment); - - dlg.addTab("Actual", actual.isNull() ? QPixmap() : QPixmap::fromImage(actual)); - if (!expected.isNull()) { - dlg.addTab("Expected", QPixmap::fromImage(expected)); - dlg.setComment(fullComment); - } else { - dlg.setComment(fullComment + "\n" - "If you click on 'Yes' the 'Actual' image will become the\n" - "expected image, and will be used for future comparisons.\n"); - } - - if ( dlg.exec() == QDialog::Accepted ) - return true; - } - - return false; -} - -/*! - \internal - Compares the \a actual and \a expected images and returns true if the images are - the same. If \a strict is false, small differences between the images are allowed. -*/ -bool QSystemTest::imagesAreEqual( const QImage &actual, const QImage &expected, bool strict ) -{ - // images are considered the same if both contain a null image - if (actual.isNull() && expected.isNull()) - return true; - - // images are not the same if one images contains a null image - if (actual.isNull() || expected.isNull()) - return false; - - // images do not have the same size - if (actual.size() != expected.size()) - return false; - - QImage a = actual.convertToFormat(QImage::Format_ARGB32); - QImage e = expected.convertToFormat(QImage::Format_ARGB32); - - bool equal = true; - int threshold = 80; - for ( int y=0; y<a.height(); y++ ) { - for ( int x=0; x<a.width(); x++ ) { - QRgb actPix = a.pixel( x, y ); - QRgb expPix = e.pixel( x, y ); - - if ( qAlpha(actPix)==0 && qAlpha(expPix)==0 ) - continue; - if ( actPix != expPix) { - if (strict || - (qAbs(qRed(actPix) - qRed(expPix)) + - qAbs(qGreen(actPix) - qGreen(expPix)) + - qAbs(qBlue(actPix) - qBlue(expPix)) > threshold) - ) { - equal = false; - goto done; - } - } - } - } - -done: - return equal; -} - -/*! - Appends \a description to the list of manual test execution steps. - The complete list will be shown: - \list - \o When in \a -force-manual mode: in a prompt dialog at the end of the test function. - \o When NOT in \a -force-manual mode: in a prompt dialog immediately before any test automation -function is called, i.e. currentTitle(), verify(), getText(), etc. - \endlist - - \sa prompt -*/ -void QSystemTest::manualTest( const QString &description ) -{ - if (m_auto_mode) { - skip("Manual test skipped", SkipSingle); - return; - } - - QString descr = description; - if (descr.startsWith("MAGIC_COMMAND:")) { - descr.remove("MAGIC_COMMAND:"); - } else { - bool magic_data_replaced = false; - int pos = descr.indexOf("MAGIC_DATA"); - while (pos >= 0 - && m_manual_command_data.count() > 0) { - descr.remove(pos,10); - descr.insert(pos,m_manual_command_data.takeFirst()); - magic_data_replaced = true; - pos = descr.indexOf("MAGIC_DATA"); - } - - if (m_manual_command_data.count() > 1) { - if (!m_manual_command_data[0].contains("MAGIC_DATA") - && m_manual_command_data[1].contains("MAGIC_DATA")) { - // swap data 1 and data 0 ... - QString tmp = m_manual_command_data.takeFirst(); - descr.append(m_manual_command_data.takeFirst()); - magic_data_replaced = true; - descr.replace("MAGIC_DATA", tmp); - } - } - - while (m_manual_command_data.count() > 0) { - descr += " " + m_manual_command_data.takeFirst(); - } - - if (descr.contains("MAGIC_DATA") && alternative_command_data.count() > 0) { - descr.replace("MAGIC_DATA", alternative_command_data.takeFirst()); - } - } - m_manual_commands += QString("%1 %2\n").arg(++m_query_count).arg(descr); - - m_manual_command_data.clear(); - alternative_command_data.clear(); -} - -/*! - \internal - Adds 'magic' data to a fifo. This data is used by \c manualTest to replace 'MAGIC_DATA' placeholders - in their text. -*/ -void QSystemTest::manualTestData( const QString &description, bool isAlternative ) -{ - if (isAlternative) { - alternative_command_data.append(description); - } else { - QString descr = description; - int pos = descr.lastIndexOf("MAGIC_DATA"); - while (pos >= 0 - && m_manual_command_data.count() > 0) { - descr.remove(pos,10); - descr.insert(pos,m_manual_command_data.takeLast()); - pos = descr.lastIndexOf("MAGIC_DATA"); - } - m_manual_command_data.append(descr); - } -} - -/*! - \internal - Sends a query test message \a msg to the Application Under Test (AUT) identified by \a queryPath and returns the reply message. An error is logged in the testresult if the AUT doesn't respond within \a timeout ms. - - Note that it is seldom necessery to call query directly. -*/ -QTestMessage QSystemTest::query( const QTestMessage &msg, const QString &queryPath, int timeout ) -{ -// manualTest( msg.event() + QString("--") + msg.msgId() + "--" + msg.toString() ); - if (m_run_as_manual_test) { - manualTest( QString("%1 -- %2 -- $3").arg(msg.event()).arg(msg.msgId()).arg(msg.toString()) ); - QTestMessage reply; - reply["status"] = "OK"; - return reply; - } else { - if (!m_manual_commands.isEmpty()) - showPromptDialog(); - } - - QTestMessage message(msg); - message["queryPath"] = queryPath; - query_failed = false; - m_error_msg = QTestMessage(); - m_last_msg_sent = QTestMessage(); - - if (-1 != fatal_timeouts && timeouts >= fatal_timeouts) { - QTestMessage reply; - reply["status"] = "ERROR_FATAL_TIMEOUT"; - setQueryError(reply); - return reply; - } - - QTestMessage reply; - reply["status"] = "ERROR_UNSET_REPLY"; - - m_last_msg_sent = message; - - if (m_test_app) { - if (!m_test_app->sendMessage( message, reply, timeout )) { - setQueryError(reply); - return reply; - } - } else { - setQueryError( "No Application Under Test (AUT) available" ); - } - - QString warning = reply["warning"].toString(); - if (!warning.isEmpty()) { - qWarning("In response to '%s', received warning from test system: %s", qPrintable(message.event()), qPrintable(warning)); - } - if (reply["status"] == "ERROR_REPLY_TIMEOUT" || reply["status"] == "ERROR_NO_CONNECTION") ++timeouts; - - return reply; -} - -/*! - \internal - Sends a query specified with \a message to the Application Under Test (AUT). If the query was successful and \a reply is not null the reply message is returned in \a reply. - - The function returns true if the query result string equals \a passResult and false if it equals - \a failResult. The function also returns false in cases where a query failure has occurred. - - The \a queryPath can be used to specify which specific application/object the query is intended for. - - The \a timeout parameter can be used to limit the time the query will wait for a reply. - - If the function is NOT called from within a test macro such as QVERIFY, QCOMPARE, etc, the function - will also write a warning message to the display describing the error. -*/ -bool QSystemTest::queryPassed( const QStringList &passResult, const QStringList &failResult, - const QTestMessage &message, const QString &queryPath, QTestMessage *reply, int timeout ) -{ - QTime t; - if (m_verbose) t.start(); - - QTestMessage msg(message); - - if (m_expect_app_close) { - msg["expectClose"] = "yes"; - } - - QTestMessage ret = query( BT(msg), queryPath, timeout ); - if (reply) *reply = ret; - QString query_msg = message.event(); - if (query_msg == "getProperty") - query_msg += "(" + message["property"].toString() + ")"; - - if (!queryFailed()) { - if (passResult.contains( ret["status"].toString() )) { - if (m_verbose) { - qLog(QtUitest) << QString("query '%1' took %2 ms").arg(query_msg).arg(t.elapsed()).toLatin1(); - } - return true; - } - if (failResult.contains( ret["status"].toString() )) { - if (m_verbose) { - qLog(QtUitest) << QString("query '%1' took %2 ms").arg(query_msg).arg(t.elapsed()).toLatin1(); - } - return false; - } - } - - if (m_verbose) { - qLog(QtUitest) << QString("query '%1' took %2 ms").arg(message.event()).arg(t.elapsed()).toLatin1(); - } - return setQueryError( ret ); -} - -/*! - \internal - \overload - Equivalent to queryPassed() with passResult and failResult a single-element string list. -*/ -bool QSystemTest::queryPassed( const QString &passResult, const QString &failResult, - const QTestMessage &message, const QString &queryPath, QTestMessage *reply, int timeout ) -{ - QStringList pass; - QStringList fail; - if (!passResult.isEmpty()) pass << passResult; - if (!failResult.isEmpty()) fail << failResult; - return queryPassed(pass, fail, message, queryPath, reply, timeout); -} - - -/*! - \internal - Implementation for the two public getSetting functions. -*/ -QVariant QSystemTest::getSetting( const QString &org, const QString &app, const QString &file, const QString &group, const QString &key ) -{ - QTestMessage message("getSetting"); - if (!org.isNull()) message["org"] = org; - if (!app.isNull()) message["app"] = app; - if (!file.isNull()) message["path"] = file; - message["group"] = group; - message["key"] = key; - - QVariant out; - QTestMessage reply; - if (!queryPassed("OK", "", BT(message), "", &reply)) return out; - if (!reply.contains("getSetting")) { - reply["status"] = "reply was missing return value"; - setQueryError(reply); - return QVariant(); - } - return reply["getSetting"]; -} - -/*! - \internal - Implementation for the two public setSetting functions. -*/ -void QSystemTest::setSetting( const QString &org, const QString &app, const QString &file, const QString &group, const QString &key, const QVariant &value ) -{ - QTestMessage message("setSetting"); - if (!org.isNull()) message["org"] = org; - if (!app.isNull()) message["app"] = app; - if (!file.isNull()) message["path"] = file; - message["group"] = group; - message["key"] = key; - message["value"] = value; - - queryPassed("OK", "", BT(message)); -} - -/*! - \internal - Processes incoming messages from the system under test -*/ -void QSystemTest::processMessage( const QTestMessage &msg ) -{ - if (msg.event().startsWith("key")) { - resetEventTimer(); - if (recorded_events_as_code) - parseKeyEventToCode( msg ); - return;// true; - } else if (msg.event().startsWith("mouse")) { - resetEventTimer(); - return;// true; - } else if (msg.event() == "information") { - if (recorded_events_as_code) - recordedEvent( msg ); - return;// true; - } else if (msg.event() == "command") { - if (recorded_events_as_code) - recordedEvent( msg ); - return;// true; - } else if (msg.event() == "recordedEvents") { - recordedEvent( msg ); - return;// true; - } else if (msg.event() == "appGainedFocus") { - QString new_app = (msg)["appName"].toString(); - if (new_app != current_application) { - current_application = new_app; - current_app_version = (msg)["appVersion"].toString(); - emit appGainedFocus(current_application); - } - return;// true; - } else if (msg.event() == "appBecameIdle") { - emit appBecameIdle((msg)["appName"].toString()); - } - - return;// false; -} - -struct StaticQtMetaObject : public QObject -{ - static const QMetaObject *get() - { return &static_cast<StaticQtMetaObject*> (0)->staticQtMetaObject; } -}; - -/*! - \internal -*/ -void QSystemTest::parseKeyEventToCode( const QTestMessage &msg) { - bool pressed = (msg.event() == "keyPress"); - - Qt::Key key = (Qt::Key)(msg)["key"].toInt(); - Qt::KeyboardModifiers mod = (Qt::KeyboardModifiers)(msg)["mod"].toInt(); - bool autoRepeat = (msg)["rep"].toBool(); - if (autoRepeat) return; - - QMetaObject const *qt = StaticQtMetaObject::get(); - QMetaEnum key_enum = qt->enumerator(qt->indexOfEnumerator("Key")); - char const *key_str = key_enum.valueToKey(key); - - if (pressed) { - key_hold_started = QTime::currentTime(); - return; - } - - int timePressed = key_hold_started.msecsTo(QTime::currentTime()); - bool is_script = true; //inherits("QScriptSystemTest",QString()); - - QString key_identifier = (is_script) ? "Qt." : "Qt::"; - key_identifier += QString::fromLatin1(key_str); - - QString code; - if (!is_script) code += "QCHECKED( "; - if (timePressed > 300) { - code += QString("keyClickhold( %1, %2 )").arg( key_identifier ).arg( timePressed ); - } else { - code += QString("keyClick( %1 )").arg( key_identifier ); - } - if (!is_script) code += " )"; - code += ";"; - - QTestMessage out("CODE"); - out["code"] = code; - recordedEvent( out ); -} - -/*! - \internal -*/ -bool QSystemTest::recentEventRecorded() -{ - if (event_timer == 0) { - return false; - } else { - return event_timer->elapsed() < 4800; - } -} - -/*! - \internal -*/ -void QSystemTest::resetEventTimer() -{ - if (event_timer == 0) { - event_timer = new QTime(); - } - - event_timer->start(); -} - -/*! - \internal - Signals the test that event recording needs to be switched on. -*/ -void QSystemTest::recordPrompt() -{ - record_prompt = true; -} - -void compressCode(QString &code) -{ - QString old_c; - QString c = code; - while (old_c != c) { - old_c = c; - - // toggling a checkbox also causes it to be selected. - static QRegExp setCheckedSelect( - "setChecked\\( (true|false), ([^\n]+) \\);\n" - "select\\( \\2 \\);\n", - Qt::CaseSensitive, QRegExp::RegExp2); - while (-1 != setCheckedSelect.indexIn(c)) - c.replace(setCheckedSelect, "setChecked( \\1, \\2 );\n"); - static QRegExp selectSetChecked( - "select\\( ([^\n]+) \\);\n" - "setChecked\\( (true|false), \\1 \\);\n", - Qt::CaseSensitive, QRegExp::RegExp2); - while (-1 != selectSetChecked.indexIn(c)) - c.replace(selectSetChecked, "setChecked( \\2, \\1 );\n"); - - // We get an enter event for each key press typically, so - // compress enter("f"), enter("fo"), enter("foo") into enter("foo") - static QRegExp enter( - "enter\\( [^\n]+(, [^\n]+) \\);\n" - "enter\\( ([^\n]+)\\1 \\);\n", - Qt::CaseSensitive, QRegExp::RegExp2); - while (-1 != enter.indexIn(c)) - c.replace(enter, "enter( \\2\\1 );\n"); - - // Do the above also when there is no querypath - static QRegExp enter2( - "enter\\( \"(?:[^\"\\\\]*(?:\\\\.)*)*\" \\);\n" - "enter\\( \"((?:[^\"\\\\]*(?:\\\\.)*)*)\" \\);\n", - Qt::CaseSensitive, QRegExp::RegExp2); - while (-1 != enter2.indexIn(c)) - c.replace(enter2, "enter( \"\\1\" );\n"); - - // We get a select tab bar event each time we switch tabs, so - // compress them. - static QRegExp selectTabBar( - "select\\( [^\n]+, tabBar\\(\\) \\);\n" - "select\\( ([^\n]+), tabBar\\(\\) \\);\n", - Qt::CaseSensitive, QRegExp::RegExp2); - while (-1 != selectTabBar.indexIn(c)) - c.replace(selectTabBar, "select( \\1, tabBar() );\n"); - - // Not sure how to handle empty selects. Strip them out. - static QRegExp selectNothing( - "select\\( (\"\")? \\);\n"); - while (-1 != selectNothing.indexIn(c)) - c.replace(selectNothing, QString()); - - // Strip out redundant selects (eg, when selecting from combobox) - static QRegExp selectTestAbstractItemView( - "select\\( \"[^\n]+\", \"TestAbstractItemView\\[\\w*\\]\" \\);\n"); - while (-1 != selectTestAbstractItemView.indexIn(c)) - c.replace(selectTestAbstractItemView, QString()); - - } - code = c; -} - -QString escapeString(QString const& in) -{ - QString out; - foreach (QChar c, in) { - if (c == '"') - out += "\\\""; - else if (c == '\\') - out += "\\\\"; - else if (c == '\n') - out += "\\n"; - else - out += c; - } - return out; -} - -QString widgetParameter(QString const& widget) -{ - QString ret; - ret = '"' + escapeString(widget) + '"'; - return ret; -} - -QString recordedEventsToCode( QList<RecordEvent> const &events ) -{ - QStringList statements; - QString focusWidget; - foreach (RecordEvent e, events) { - QString cmd; - switch (e.type) { - case RecordEvent::GotFocus: - // There is currently no API for simply navigating to a widget. - // If one were added, we would do something like this: - // statements << QString("setFocus( \"%1\" );").arg(e.widget); - focusWidget = e.widget; - break; - - case RecordEvent::Entered: - cmd = QString("enter( \"%1\"").arg(escapeString(e.data.toString())); - if (!e.widget.isEmpty() && e.widget != focusWidget) - cmd += QString(", %1").arg(widgetParameter(e.widget)); - cmd += " );"; - statements << cmd; - focusWidget = e.widget; - break; - - case RecordEvent::Activated: - statements << QString("select( %1 );").arg(widgetParameter(e.widget)); - focusWidget = QString(); - break; - - case RecordEvent::Selected: - cmd = QString("select( \"%1\"").arg(escapeString(e.data.toString())); - if (!e.widget.isEmpty() && e.widget != focusWidget) - cmd += QString(", %1").arg(widgetParameter(e.widget)); - cmd += " );"; - statements << cmd; - focusWidget = QString(); - break; - - case RecordEvent::CheckStateChanged: - cmd = QString("setChecked( %1").arg(e.data.toBool() ? "true" : "false"); - if (!e.widget.isEmpty() && e.widget != focusWidget) - cmd += QString(", %1").arg(widgetParameter(e.widget)); - cmd += " );"; - statements << cmd; - focusWidget = e.widget; - break; - - case RecordEvent::TitleChanged: - statements << QString("waitForTitle( \"%1\" );").arg(escapeString(e.data.toString())); - focusWidget = QString(); - break; - - case RecordEvent::MessageBoxShown: { - QVariantMap map = e.data.toMap(); - QString title = map["title"].toString(); - QString text = map["text"].toString(); - statements << QString("// Message box shown, title: \"%1\", text: \"%2\"").arg(escapeString(title)).arg(escapeString(text)); - focusWidget = QString(); - break; - } - - default: - statements << QString("// unknown event: %1 %2 %3").arg(e.type).arg(widgetParameter(e.widget)).arg(escapeString(e.data.toString())); - break; - } - } - - return statements.join("\n"); -} - -/*! - \internal -*/ -void QSystemTest::recordedEvent( const QTestMessage &msg ) { - if (msg.event() == "recordedEvents") { - recordEvents( (msg)["events"].value< QList<RecordEvent> >() ); - } -} - -void QSystemTest::recordEvents(QList<RecordEvent> const& events) -{ - recorded_events << events; - QString out = recordedEventsToCode( recorded_events ); - recorded_events.clear(); - if (!out.isEmpty()) { - m_recorded_code += out + "\n"; - - // For debugging purposes, allow code compression to be skipped. - static bool skip_compression = !qgetenv("QTUITEST_DEBUG_RECORD").isEmpty(); - if (!skip_compression) compressCode(m_recorded_code); - if (m_recorded_events_edit && m_recorded_events_edit->isVisible()) { - m_recorded_events_edit->setPlainText(m_recorded_code); - m_recorded_events_edit->moveCursor(QTextCursor::End); - m_recorded_events_edit->ensureCursorVisible(); - } - QTestIDE::instance()->recordedCode(m_recorded_code); - } -} -/* - Returns the PATH environment variable, i.e. the part 'after' PATH=. -*/ -QString QSystemTest::PATH() -{ - QStringList env = QProcess::systemEnvironment(); - foreach (QString line, env) { - if (line.startsWith("PATH=", Qt::CaseInsensitive)) - return line.mid(line.indexOf("=")+1); - } - return ""; -} - -/* - Traverses through the environment PATH setting to find app \a appName. - On Mac, this might include the '<appName>.app/Contents/MacOS/<appName>' location. -*/ -QString QSystemTest::which( const QString &appName ) -{ - QString path = PATH(); - if (!path.isEmpty()) { - QStringList path_list; -#if defined Q_OS_WIN32 - path_list = path.split(";"); -#else - path_list = path.split(":"); -#endif - foreach (QString p, path_list) { - QString fname = p + QDir::separator() + appName; - if (QFile::exists(fname)) return fname; -#if defined Q_OS_MAC - QString mac_name = fname + ".app/Contents/MacOS/" + appName; - if (QFile::exists(mac_name)) return mac_name; -#endif -#if defined Q_OS_WIN32 - if (QFile::exists(fname+".exe")) return fname+".exe"; - if (QFile::exists(fname+".bat")) return fname+".bat"; -#endif - } - } - return ""; -} - -QString QSystemTest::processEnvironment( QString const& in ) const -{ - struct SystemEnvironment { - static QMap<QString,QString> get() { - QMap<QString,QString> ret; - QStringList env = QProcess::systemEnvironment(); - foreach (QString str, env) { - if (str.contains('=')) { - ret[str.left(str.indexOf('=')).toUpper()] = str.mid(str.indexOf('=') + 1); - } - } - return ret; - } - }; - static const QMap<QString,QString> environment( SystemEnvironment::get() ); - - QString out; - static QRegExp re("\\$[{(]?([A-Za-z0-9_]+)[})]?"); - int offset = 0; - while (true) { - int index = re.indexIn(in, offset); - if (-1 == index) { - out += in.mid(offset); - break; - } - out += in.mid(offset, index - offset); - out += environment.value(re.cap(1).toUpper()); - offset += re.matchedLength(); - } - - return out; -} - -QStringList QSystemTest::processEnvironment( QStringList const& in ) const -{ - QStringList out; - foreach (QString string, in) { - out << processEnvironment(string); - } - return out; -} - -void QSystemTest::showPromptDialog( const QString &text ) -{ - QString promptText; - if (text.isNull()) { - promptText = m_manual_commands; - m_manual_commands.clear(); - } else { - promptText = text; - } - - if (promptText.isEmpty()) { - recordEvents( "" ); - return; - } - - int level1_count = 0; - int level2_count = 0; - int level3_count = 0; - QStringList prompt_text = promptText.split("\n"); - for (int i=0; i<prompt_text.count(); i++) { - if (prompt_text[i].startsWith("* ")) { - prompt_text[i] = QString("%1. %2").arg(++level1_count).arg(prompt_text[i].mid(1)); - level2_count=0; - } else if (prompt_text[i].startsWith("** ")) { - prompt_text[i] = QString(" %1. %2").arg(++level2_count).arg(prompt_text[i].mid(2)); - level3_count=0; - } else if (prompt_text[i].startsWith("*** ")) { - prompt_text[i] = QString(" %1. %2").arg(++level2_count).arg(prompt_text[i].mid(3)); - } - } - -#ifdef Q_OS_MAC - QString active_window; - if (!runAsManualTest()) active_window = activeWindow(); -#endif - - QDialog promptWindow(0, Qt::WindowStaysOnTopHint); - Ui::ManualVerificationDlg promptUi; - promptUi.setupUi(&promptWindow); - - if (!isConnected()) { - promptUi.learnButton->hide(); - } - - promptUi.test_steps->setText( prompt_text.join("\n") ); - if (QTest::currentTestFunction() != NULL) { - if (QTest::currentDataTag() != NULL) { - promptWindow.setWindowTitle( QString("Manual Verification: %1 (%2)").arg(QTest::currentTestFunction()).arg(QTest::currentDataTag()) ); - } else { - promptWindow.setWindowTitle( QString("Manual Verification: %1").arg(QTest::currentTestFunction()) ); - } - } - - QDialog failureWindow(&promptWindow); - Ui::FailureDlg failureUi; - failureUi.setupUi(&failureWindow); - connect( promptUi.cancelButton, SIGNAL(clicked()), &failureWindow, SLOT(exec()) ); - connect( promptUi.learnButton, SIGNAL(clicked()), this, SLOT(recordPrompt()) ); - connect( promptUi.learnButton, SIGNAL(clicked()), &promptWindow, SLOT(close()) ); - connect( promptUi.abort_button, SIGNAL(clicked()), &promptWindow, SLOT(close()) ); -//FIXME connect( promptUi.abort_button, SIGNAL(clicked()), this, SLOT(abortPrompt()) ); - - connect( failureUi.buttonBox, SIGNAL(accepted()), &promptWindow, SLOT(reject()) ); - - record_prompt = false; - abort_prompt = false; - promptWindow.exec(); - - if (abort_prompt) { - skip( "Manual verification step has been aborted", SkipSingle ); -#ifdef Q_OS_MAC - if (!runAsManualTest()) activateWindow(active_window); -#endif - return; - } - - if (record_prompt) { - recordEvents( prompt_text.join("\n") ); -#ifdef Q_OS_MAC - if (!runAsManualTest()) activateWindow(active_window); -#endif - return; - } - bool ret = (promptWindow.result() == QDialog::Accepted); - - /* If we fail with no text, encourage user to enter text */ - if (learnMode() == LearnNone) { - while (!ret && failureUi.failureEdit->toPlainText().isEmpty() ) { - int clicked = QMessageBox::warning( 0, "No message entered", - "You have not entered a failure message. This may make it difficult to determine " - "the reason for failure from the test logs. Continue without entering a message?", - QMessageBox::Ok, QMessageBox::Cancel ); - if (clicked == QMessageBox::Ok) break; - QMetaObject::invokeMethod(promptUi.cancelButton, "click", Qt::QueuedConnection); - promptWindow.exec(); - ret = (promptWindow.result() == QDialog::Accepted); - } - } - - QString failureMessage = failureUi.failureEdit->toPlainText(); - - if (ret) { -#ifdef Q_OS_MAC - if (!runAsManualTest()) activateWindow(active_window); -#endif - return; - } - - QString message = "Manual verification steps failed"; - if (!failureMessage.isEmpty()) { - message += "; " + failureMessage; - } - fail( message ); - -#ifdef Q_OS_MAC - if (!runAsManualTest()) activateWindow(active_window); -#endif -} - -bool QSystemTest::isConnected() -{ - return m_test_app && m_test_app->isConnected(); -} - diff --git a/libqsystemtest/qsystemtestmaster.cpp b/libqsystemtest/qsystemtestmaster.cpp deleted file mode 100644 index 63ba077..0000000 --- a/libqsystemtest/qsystemtestmaster.cpp +++ /dev/null @@ -1,108 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of QtUiTest. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qsystemtestmaster_p.h" - -#include <qsystemtest.h> - -#include <QFile> -#include <QDir> -#include <QTextStream> -#include <QIODevice> - -// ************************************************************************************** -// ************************************************************************************** - -QSystemTestMaster::QSystemTestMaster( QSystemTest *testCase ) - : QTestProtocol() - , app_name() - , app_version() - , qt_version() - , test_case(testCase) -{ -} - -QSystemTestMaster::~QSystemTestMaster() -{ -} - -void QSystemTestMaster::queryName() -{ - QTestMessage reply; - sendMessage(QTestMessage("appName"), reply, 40000); - app_name = reply["appName"].toString(); - app_version = reply["appVersion"].toString(); - qt_version = reply["qtVersion"].toString(); -} - -void QSystemTestMaster::processMessage( QTestMessage *msg ) -{ - if (msg->event() == "APP_NAME") { - app_name = (*msg)["appName"].toString(); - app_version = (*msg)["appVersion"].toString(); - qt_version = (*msg)["qtVersion"].toString(); - } else { - // Leave all processing to the testcase - if (test_case != 0) { - test_case->processMessage( *msg ); - } - } -} - -QString QSystemTestMaster::appName() -{ - return app_name; -} - -QString QSystemTestMaster::appVersion() -{ - return app_version; -} - -QString QSystemTestMaster::qtVersion() -{ - return qt_version; -} - -void QSystemTestMaster::onReplyReceived( QTestMessage * /*reply*/ ) -{ -} - diff --git a/libqsystemtest/qsystemtestmaster_p.h b/libqsystemtest/qsystemtestmaster_p.h deleted file mode 100644 index f82bbf0..0000000 --- a/libqsystemtest/qsystemtestmaster_p.h +++ /dev/null @@ -1,75 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of QtUiTest. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QSYSTEMTESTMASTER_P_H -#define QSYSTEMTESTMASTER_P_H - -#include "qtestprotocol_p.h" -#include <QObject> -#include <qtuitestglobal.h> - -class QSystemTest; - -class QSYSTEMTEST_EXPORT QSystemTestMaster : public QTestProtocol -{ -public: - QSystemTestMaster( QSystemTest *testCase ); - virtual ~QSystemTestMaster(); - - QString appName(); - QString appVersion(); - QString qtVersion(); - - virtual void onReplyReceived( QTestMessage *reply ); - -protected: - virtual void processMessage( QTestMessage *msg ); - -private: - void queryName(); - QString app_name; - QString app_version; - QString qt_version; - QSystemTest *test_case; -}; - -#endif - diff --git a/libqsystemtest/qtestide.cpp b/libqsystemtest/qtestide.cpp deleted file mode 100644 index cb4a271..0000000 --- a/libqsystemtest/qtestide.cpp +++ /dev/null @@ -1,221 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of QtUiTest. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qtestide.h" -#include "qsystemtest.h" -#include <QScriptContext> -#include <QScriptContextInfo> -#include <QScriptValueIterator> -#include <QPixmap> - -QTestIDE* QTestIDE::instance() -{ - static QTestIDE instance; - return &instance; -} - -QTestIDE::QTestIDE() - : m_sysTest(0) -{ - must_stop_event_recording = false; - event_recording_aborted = false; -} - -QTestIDE::~QTestIDE() -{ -} - -void QTestIDE::setSystemTest(QSystemTest *sysTest) -{ - m_sysTest = sysTest; -} - -/*! - \internal - Opens a socket connection to a remote test tool and uses the connection to - communicate with the connected tool. -*/ -void QTestIDE::openRemote( const QString &ip, int port ) -{ - m_remote.openRemote(ip, port); -} - -bool QTestIDE::isConnected() -{ - return m_remote.isConnected(); -} - -void QTestIDE::scriptSyntaxError(const QString& errorMsg, const QString& file, int line) -{ - if (errorMsg.isEmpty()) { - qWarning(QString("Syntax Error in %1, near line %2").arg(file).arg(line).toLatin1()); - } else { - qWarning(QString("Syntax Error in %1, near line %2: %3").arg(file).arg(line).arg(errorMsg).toLatin1()); - } -} - -bool QTestIDE::queryBreakpoint(const QString& file, int line, const QString& function, int depth) -{ - if (m_remote.isConnected()) { - QTestMessage ide_msg("queryBreakpoint"); - ide_msg["file"] = file; - ide_msg["line"] = line; - ide_msg["function"] = function; - ide_msg["depth"] = depth; - QTestMessage reply; - m_remote.sendMessage( ide_msg, reply, -1 ); - return (reply["status"] == "sendContext"); - } - return false; -} - -void QTestIDE::breakpointContext(const QScriptContext* scriptContext) -{ - QTestMessage ide_msg("context"); - int i=0; - for (const QScriptContext *c = scriptContext; - c && c->parentContext(); - c = c->parentContext(), ++i) { - QVariantMap contextMap; - contextToMap(c, contextMap); - ide_msg[QString("context_%1").arg(i)] = contextMap; - } - ide_msg["context_count"] = i; - QTestMessage reply; - m_remote.sendMessage( ide_msg, reply, -1 ); -} - -void QTestIDE::eventRecordingStarted(const QString& file, int line, const QString& steps) -{ - if (m_remote.isConnected()) { - QTestMessage message("EVENT_RECORDING_STARTED"); - message["file"] = file; - message["line"] = line; - message["steps"] = steps; - m_remote.postMessage( message ); - - m_remote.must_stop_event_recording = false; - m_remote.event_recording_aborted = false; - } -} - -void QTestIDE::recordedCode(const QString &code) -{ - if (m_remote.isConnected()) { - QTestMessage ide_msg("recordedCode"); - ide_msg["code"] = code; - m_remote.postMessage( ide_msg ); - } -} - -bool QTestIDE::mustStopEventRecording() { - return m_remote.must_stop_event_recording; -} - -bool QTestIDE::eventRecordingAborted() { - return m_remote.event_recording_aborted; -} - -void QTestIDE::failureScreenshot(const QString &screenshot, const QString &file, int line, const QString &function) -{ - if (m_remote.isConnected()) { - QTestMessage msg("failure_screenshot"); - msg["screenshot"] = screenshot; - msg["filename"] = file; - msg["line"] = line; - msg["testfunction"] = function; - m_remote.postMessage(msg); - } -} - -void QTestIDE::newTestData(const QString &file) -{ - if (m_remote.isConnected()) { - QTestMessage msg("NEW_TESTDATA"); - msg["filename"] = file; - m_remote.postMessage(msg); - } -} - -bool QTestIDE::verifyImage(const QPixmap &actual, const QPixmap &expected, const QString &comment) -{ - QTestMessage returnValue; - QTestMessage msg("VERIFY_IMAGE"); - msg["actual"] = actual; - msg["expected"] = expected; - msg["comment"] = comment; - - if (m_remote.sendMessage( msg, returnValue, -1 ) && returnValue["status"] == "OK") { - return returnValue["accepted"].toBool(); - } else { - return false; -// return fail( "Verification of pixmap not possible: remote test tool did not correctly respond." ); - } -} - -void QTestIDE::contextToMap(const QScriptContext* scriptContext, QVariantMap &contextMap) -{ - QVariantMap vars; - QScriptContextInfo ctxInfo(scriptContext); - - QScriptValue locals = scriptContext->activationObject(); - if (!locals.isValid()) return; - QScriptValueIterator it(locals); - while (it.hasNext()) { - it.next(); - if (!it.value().toVariant().isValid()) { - continue; - } - vars[it.name()] = it.value().toVariant(); - } - - contextMap["vars"] = vars; - contextMap["file"] = ctxInfo.fileName(); - contextMap["line"] = ctxInfo.lineNumber(); - - if (ctxInfo.functionName().isEmpty()) { - contextMap["function"] = m_sysTest ? m_sysTest->currentTestFunction() : QString("unknown"); - } else { - contextMap["function"] = ctxInfo.functionName(); - contextMap["funcStart"] = ctxInfo.functionStartLineNumber(); - contextMap["funcEnd"] = ctxInfo.functionEndLineNumber(); - } -}
\ No newline at end of file diff --git a/libqsystemtest/qtestide.h b/libqsystemtest/qtestide.h deleted file mode 100644 index 0349b86..0000000 --- a/libqsystemtest/qtestide.h +++ /dev/null @@ -1,93 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of QtUiTest. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QTESTIDE_H -#define QTESTIDE_H - -#include "qtestremote_p.h" -#include <QVariantMap> - -class QSystemTest; -class QString; -class QScriptContext; - -class QSYSTEMTEST_EXPORT QTestIDE : public QObject -{ - Q_OBJECT - -public: - static QTestIDE* instance(); - - QTestIDE(); - virtual ~QTestIDE(); - void setSystemTest( QSystemTest* ); - - void openRemote( const QString &ip, int port ); - bool isConnected(); -// virtual void processMessage( QTestMessage *msg ); - - void scriptSyntaxError(const QString&, const QString&, int); - bool queryBreakpoint(const QString&, int, const QString&, int); - void breakpointContext(const QScriptContext*); - - void eventRecordingStarted(const QString&, int, const QString&); - void recordedCode(const QString&); - bool mustStopEventRecording(); - bool eventRecordingAborted(); - - void failureScreenshot(const QString&, const QString&, int, const QString&); - void newTestData(const QString&); - bool verifyImage(const QPixmap &, const QPixmap&, const QString&); - -signals: - void abort(); - void syntaxError(const QString&, const QString&, int); - -private: - void contextToMap(const QScriptContext* scriptContext, QVariantMap&); - bool must_stop_event_recording; - bool event_recording_aborted; - QTestRemote m_remote; - QSystemTest *m_sysTest; - -}; - -#endif diff --git a/libqsystemtest/qtestprotocol.cpp b/libqsystemtest/qtestprotocol.cpp deleted file mode 100644 index 9246a28..0000000 --- a/libqsystemtest/qtestprotocol.cpp +++ /dev/null @@ -1,1182 +0,0 @@ -/************************************************************************** -** -** This file is part of Qt Creator -** -** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). -** -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** Commercial Usage -** -** Licensees holding valid Qt Commercial licenses may use this file in -** accordance with the Qt Commercial License Agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Nokia. -** -** GNU Lesser General Public License Usage -** -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. -** -**************************************************************************/ - -/* - This cpp file contains a number of socket related classes that are used heavily in QtUiTest. - The classes are documented later in the file. -*/ - -#include "qtestprotocol_p.h" - -#include <QApplication> -#include <QString> -#include <QTimer> -#include <QUuid> -#include <QFileInfo> -#include <QDir> -#include <QtNetwork/QTcpSocket> -#include <QtNetwork/QTcpServer> -#include <QtNetwork/QHostAddress> -#include <QtNetwork/QHostInfo> -#include <QPointer> - -#include <QDebug> -#define qLog(A) if (1); else qDebug() - -#if defined(Q_OS_WIN32) && !defined(Q_OS_TEMP) -# include <io.h> -#endif - -static const int CONNECT_TIMEOUT = 20000; - -static const quint32 TEST_MSG_SIGNATURE = 0xEDBAEDBA; -static const quint32 TEST_MSG_END = 0xEDBAABDE; -static const quint8 TEST_MSG_VERSION = 3; -static uint g_unique_id = 0; - -bool waitForSignal(QObject* object, const char* signal, int timeout) -{ -#ifdef QTUITEST_TARGET - return QtUiTest::waitForSignal(object, signal, timeout); -#else - QEventLoop loop; - QTimer dummy; - dummy.setInterval(1000); - if (!QObject::connect(object, signal, &dummy, SLOT(start()))) - return false; - if (!QObject::connect(object, signal, &loop, SLOT(quit()))) - return false; - QTimer::singleShot(timeout, &loop, SLOT(quit())); - loop.exec(); - return dummy.isActive(); -#endif -} - -void wait(int timeout) -{ -#ifdef QTUITEST_TARGET - QtUiTest::wait(timeout); -#else - QEventLoop loop; - QTimer::singleShot(timeout, &loop, SLOT(quit())); - loop.exec(); -#endif -} - -// ******************************************************************************** -// ****************************** QTestMessage ************************************ -// ******************************************************************************** - -/* - \class QTestMessage QTestMessage.h - \inpublicgroup QtUiTestModule - - \brief The QTestMessage class can be used for exchanging messages between separate - processes. The class is never used directly but instead is used by QTestProtocol. - - The class basically wraps a number of strings (i.e. 'event' and 'message') and binary data - (i.e. a bytearray or a file) into a datastream that is sent to a peer using a socket - connection. On the receiving side a QTestMessage instance is decoding the datastream - and performs a number of sanity checks to make it a bit more robost. - - A TCP connection 'should' be reliable but in exceptional cases bytes may be lost. This - would result in the connection becoming useless because all future data reception would - be out of sync. To solve this a 'resync' function is implemented that can re-sync the datastream - by throwing away bytes until the data seems in sync again. The obvious downside is that - at least one message will be lost. - - Message format is as follows: - - Field: Length: Remarks: - - Start signature 4 Fixed value - 0xEDBAEDBA - Protocol version 1 Fixed value - 3 - Message number 2 - Event length 4 Length of following string - Event string Event length QString value - Message length 4 Length of following string - Messaga string Message length QString value - Data length 4 Length of following binary data - File data Data length Binary data - End signature 4 Fixed value - 0xEDBAABDE -*/ - -/* - \internal - - Constructs a default (empty) message. -*/ - -QTestMessage::QTestMessage(QString const &event, QVariantMap const &map) - : m_phase(0) - , m_msg_id(0) - , m_event(event) - , m_map(map) -{ -} - -QTestMessage::QTestMessage(QString const &event, const QTestMessage &other ) - : m_phase(0) - , m_msg_id(other.m_msg_id) - , m_map(other.m_map) -{ - m_event = event; -} - -QTestMessage::QTestMessage(QString const &event, QString const &queryApp, QString const &queryPath ) - : m_phase(0) - , m_msg_id(0) - , m_event(event) - , m_map(QVariantMap()) -{ - m_map["queryapp"] = queryApp; - m_map["querypath"] = queryPath; -} - -/* - \internal - - Copy constructor. -*/ - -QTestMessage::QTestMessage(const QTestMessage &other) - : m_phase(0) - , m_msg_id(other.m_msg_id) - , m_event(other.m_event) - , m_map(other.m_map) -{ -} - -/* - \internal - - Destroys the message. -*/ - -QTestMessage::~QTestMessage() -{ -} - -/* - \internal - - Assignment operator. -*/ - -QTestMessage& QTestMessage::operator=(const QTestMessage &other) -{ - m_msg_id = other.m_msg_id; - m_event = other.m_event; - m_map = other.m_map; - - return *this; -} - -QVariant &QTestMessage::operator[](QString const &key) -{ - return m_map[key.toLower()]; -} - -QVariant const QTestMessage::operator[](QString const &key) const -{ - return m_map[key.toLower()]; -} - -bool QTestMessage::contains(QString const &key) const -{ - return m_map.contains(key.toLower()); -} - -QList<QString> QTestMessage::keys() const -{ - return m_map.keys(); -} - -QString QTestMessage::toString() const -{ - QString ret; - foreach(QString k, m_map.keys()) { - if (!m_map[k].isValid()) continue; - ret += k + ": "; - if (m_map[k].canConvert<QStringList>()) ret += "'" + m_map[k].toStringList().join("','") + "'"; - else if (m_map[k].canConvert<QString>()) ret += "'" + m_map[k].toString() + "'"; - else ret += "(data)"; - ret += "\n"; - } - if (ret.endsWith("\n")) ret.chop(1); - return ret; -} - -QVariantMap QTestMessage::toMap() const -{ - return m_map; -} - -/* - \internal - Returns the event that was received. -*/ - -QString QTestMessage::event() const -{ - return m_event; -} - -/* - \internal - Returns the message number. -*/ - -quint16 QTestMessage::msgId() const -{ - return m_msg_id; -} - -bool QTestMessage::statusOK() const -{ - return m_map.contains("status") && m_map["status"].toString() == "OK"; -} - -bool QTestMessage::isNull() const -{ - return m_map.isEmpty(); -} - - -// ******************************************************************************** -// ************************* QTestServerSocket ************************************ -// ******************************************************************************** - -/* ! - \class QTestServerSocket qtestserversocket.h - \inpublicgroup QtUiTestModule - - \brief The QTestServerSocket class provides a TCP-based server. - - This class is a convenience class for accepting incoming TCP - connections. You can specify the port or have QTestServerSocket pick - one, and listen on just one address or on all the machine's - addresses. - - Using the API is very simple: subclass QTestServerSocket, call the - constructor of your choice, and implement onNewConnection() to - handle new incoming connections. There is nothing more to do. - - (Note that due to lack of support in the underlying APIs, - QTestServerSocket cannot accept or reject connections conditionally.) - - \sa QTcpSocket, QTcpServer, QHostAddress, QSocketNotifier -*/ - - -/* ! - Creates a server socket object, that will serve the given \a port - on all the addresses of this host. If \a port is 0, QTestServerSocket - will pick a suitable port in a system-dependent manner. Use \a - backlog to specify how many pending connections the server can - have. - - \warning On Tru64 Unix systems a value of 0 for \a backlog means - that you don't accept any connections at all; you should specify a - value larger than 0. -*/ - -QTestServerSocket::QTestServerSocket( quint16 port, int backlog ) - : QTcpServer() -{ - setMaxPendingConnections( backlog ); - listen( QHostAddress::Any, port ); - - if (this->serverPort() == 0) { - qWarning( QString("ERROR: port '%1' is already in use, application is aborted.").arg(port).toAscii() ); - QApplication::exit(777); - } -} - -/* ! - Destroys the socket. - - This causes any backlogged connections (connections that have - reached the host, but not yet been completely set up - to be severed. - - Existing connections continue to exist; this only affects the - acceptance of new connections. -*/ -QTestServerSocket::~QTestServerSocket() -{ -} - -/* ! - Returns true if the construction succeeded; otherwise returns false. -*/ -bool QTestServerSocket::ok() const -{ - return serverPort() > 0; -} - -/* ! - Returns the port number on which this server socket listens. This - is always non-zero; if you specify 0 in the constructor, - QTestServerSocket will pick a non-zero port itself. ok() must be true - before calling this function. - - \sa address() -*/ -quint16 QTestServerSocket::port() const -{ - return serverPort(); -} - -/* ! - Returns the address on which this object listens, or 0.0.0.0 if - this object listens on more than one address. ok() must be true - before calling this function. - - \sa port() -*/ -QString QTestServerSocket::address() const -{ - return serverAddress().toString(); -} - -void QTestServerSocket::incomingConnection( int socket ) -{ - onNewConnection( socket ); -} - -// ******************************************************************************** -// *************************** QTestProtocol ************************************ -// ******************************************************************************** - -/* - \class QTestProtocol qtestprotocol.h - \inpublicgroup QtUiTestModule - - \brief The QTestProtocol class can be used for exchanging messages between separate - processes. - - It is intended to be fast but at the same time ultra reliable and robust communication protocol. - - The main function that is used on the sending side is: - \code - myConnection.postMessage( "My-Event", "My-Message", ptr_to_my_data ); - \endcode - - On the receiving side the main function is a re-implemented 'processMessage': - \code - void MyTestConnection::processMessage( QTestMessage *msg ) - { - if (msg->event() == "My-Event") { - print( msg->message() ); - } - } - \endcode -*/ - -#include <stdio.h> - -QTestProtocol::QTestProtocol() - : QTcpSocket() - , tx_msg_id(1) - , host() - , port(0) - , onData_busy(false) - , enable_reconnect(false) - , reconnect_interval(10000) - , connect_timer() - , last_data_received(false) - , connection_valid(false) - , ping_enabled(false) - , ping_interval(10000) - , ping_timer() - , ping_count(0) - , ping_timeout_warning_issued(false) - , last_send_cmd("") - , unique_id() - , debug_on(false) -{ - static int id1 = qRegisterMetaType<QTestMessage>(); Q_UNUSED(id1); - static int id2 = qRegisterMetaType<QTestMessage*>(); Q_UNUSED(id2); - static int id3 = qRegisterMetaType<const QTestMessage*>(); Q_UNUSED(id3); - - unique_id = QString("%1").arg(++g_unique_id); - if (debug_on) { - qDebug() << QString("%1 QTestProtocol::QTestProtocol()").arg(uniqueId()).toLatin1(); - } - cur_message = 0; - rx_busy = false; - - QObject::connect( &connect_timer, SIGNAL(timeout()), this, SLOT(connectTimeout()), Qt::DirectConnection ); - - QObject::connect( this,SIGNAL(connected()),this,SLOT(onSocketConnected()), Qt::DirectConnection ); - QObject::connect( this,SIGNAL(disconnected()),this,SLOT(onSocketClosed()), Qt::DirectConnection ); - QObject::connect( this,SIGNAL(readyRead()),this,SLOT(onData()), Qt::DirectConnection ); - - // initialize. Any time is better than no time. - rx_timer.start(); -} - -/*! - Destructs the instance of QTestProtocol. -*/ - -QTestProtocol::~QTestProtocol() -{ - if (debug_on) { - qDebug() << QString("%1 QTestProtocol::~QTestProtocol()").arg(uniqueId()).toLatin1(); - } - enableReconnect( false, 0 ); - - // we can't send any more messages so disable pinging - enablePing( false ); - - // anything that is still in the tx buffer gets lost - abort(); - close(); - - while (send_msg_replies.count() > 0) - delete send_msg_replies.takeFirst(); - while (unhandled_msg.count() > 0) - delete unhandled_msg.takeFirst(); -} - -void QTestProtocol::setSocket( int socket ) -{ - if (debug_on) { - qDebug() << ( QString("%1 QTestProtocol::setSocket(socket=%2)"). - arg(uniqueId()). - arg(socket).toLatin1()); - } - setSocketDescriptor( socket ); - - rx_timer.start(); - testConnection(); -} - -void QTestProtocol::enableReconnect( bool enable, uint reconnectInterval ) -{ - if (debug_on) { - qDebug() << ( QString("%1 QTestProtocol::enableReconnect( enable=%2, interval=%3)"). - arg(uniqueId()). - arg(enable). - arg(reconnectInterval).toLatin1()); - } - enable_reconnect = enable; - reconnect_interval = reconnectInterval; -} - -/*! - Opens a socket connection to the specified \a hostname and \a port. - - After a connection is successfully opened the instance will listen for and process - incoming commands received from the remote host. -*/ -void QTestProtocol::connect( const QString& hostname, int port ) -{ - if (state() == ConnectedState) { - if (hostname == this->host && port == this->port) - return; - disconnect(); - } - - if (debug_on) { - qDebug() << ( QString("%1 QTestProtocol::connect(%2:%3)"). - arg(uniqueId()). - arg(hostname). - arg(port).toLatin1()); - } - - rx_timer.start(); - - this->host = hostname; - this->port = port; - - reconnect(); -} - -void QTestProtocol::disconnect( bool disableReconnect ) -{ - if (state() == ConnectedState) { - if (debug_on) { - qDebug() << ( QString("%1 QTestProtocol::disconnect(disableReconnect=%2)"). - arg(uniqueId()). - arg(disableReconnect).toLatin1()); - } - // be polite and tell the other side we are closing - postMessage( QTestMessage("QTEST_CLOSING_CONNECTION") ); - - // we are closing ourselves, so we don't want to reconnect - if (disableReconnect) enable_reconnect = false; - - onSocketClosed(); - } -} - -bool QTestProtocol::isConnected() -{ - return ((state() == ConnectedState) && connection_valid); -} - -bool QTestProtocol::waitForConnected( int timeout ) -{ - QTime t; - t.start(); - bool ok = false; - QTime t2; - t2.start(); - while (t.elapsed() < timeout && !ok) { - ok = QTcpSocket::waitForConnected(timeout); - if (!ok) { - wait(100); - if (t2.elapsed() > 500) { - t2.start(); - reconnect(); - } - } - } - - if (ok) { - if (debug_on) { - qDebug() << QString("%1 QTestProtocol::waitForConnected(%2) ...") - .arg(uniqueId()).arg(timeout).toLatin1(); - } - t2.start(); - while (t.elapsed() < timeout && !isConnected()) { - wait(10); - if (!isConnected() && t2.elapsed() > 500) { - postMessage( QTestMessage("QTEST_NEW_CONNECTION") ); - t2.start(); - } - } - ok = isConnected(); - } else { - qDebug() << errorStr(); - } - - if (debug_on) { - qDebug() << QString("%1 QTestProtocol::waitForConnected() ... %2 (%3 ms)").arg(uniqueId()).arg(ok ? "OK" : "FAILED" ).arg(t.elapsed()).toLatin1(); - } - return ok; -} - -/*! - \internal - Posts (e.g. non blocking) an \a event, \a message and contents of \a fileName to the remote host. -*/ - -uint QTestProtocol::postMessage(QTestMessage const &message ) -{ - if (debug_on && message.event() != "PING" && message.event() != "PONG") { - qDebug() << ( QString("%1 QTestProtocol::postMessage(%2)"). - arg(uniqueId()). - arg(message.event()).toLatin1()); - } - if (state() != ConnectedState) - return 0; - QTestMessage msg(message); - msg.m_msg_id = tx_msg_id++; - send( msg ); - return msg.m_msg_id; -} - -void QTestProtocol::onReplyReceived( QTestMessage* /*reply*/ ) -{ -} - -/*! - \internal - Sends an \a event, \a message and \a data to the remote host and waits for up to - \a timeout milliseconds for a reply. If a reply is received, the reply's message - string is placed in \a reply. -*/ -bool QTestProtocol::sendMessage( QTestMessage const &message, QTestMessage &reply, int timeout ) -{ - QTestMessage msg(message); - QPointer<QTestProtocol> safeThis(this); - bool safeDebugOn(debug_on); - QString safeUniqueId(uniqueId()); - - last_send_cmd = message.event(); - - if (state() == ConnectingState) { - wait(4000); - } - - if (state() == ConnectedState) { - msg.m_msg_id = tx_msg_id++; - - if (debug_on) { - qDebug() << ( QString("%1 QTestProtocol::sendMessage(%2) msgid=%3)"). - arg(uniqueId()). - arg(msg.event()). - arg(msg.msgId()). - toLatin1()); - } - - send( msg ); - -// QElapsedTimer t1; -// QElapsedTimer t2; - QTime t1; - t1.start(); - QTime t2; - t2.start(); - bool first_time = true; - while ( (state() == ConnectedState) && - (timeout < 0 || t1.elapsed()/*msecsSinceReference()*/ < timeout) ) { - - if (debug_on) { - if (first_time || t2.elapsed()/*msecsSinceReference()*/ > 1000) { - qDebug() << ( QString("%1 QTestProtocol::sendMessage(%2) ... waiting for reply"). - arg(uniqueId()). - arg(message.event()).toLatin1()); - t2.start(); - first_time = false; - } - } - - waitForSignal(this, SIGNAL(replyReceived()), 500); - - if (!safeThis) { - if (message["expectClose"].isValid()) { - return true; - } - if (safeDebugOn) { - qDebug() << ( QString("%1 QTestProtocol::sendMessage(%2) ... object deleted unexpectedly"). - arg(safeUniqueId). - arg(message.event()).toLatin1()); - } - reply["status"] = "ERROR: Connection was terminated unexpectedly. This may be caused by an application crash."; - reply["_q_inResponseTo"] = QString("%1\n%2").arg(message.event()).arg(message.toString()); - return false; - } else { - if (send_msg_replies.count() > 0) { - if (debug_on) { - qDebug() << ( QString("%1 QTestProtocol::sendMessage(%2) ... check replies"). - arg(uniqueId()). - arg(message.event()).toLatin1()); - } - for (int i=0; i<send_msg_replies.size(); i++) { - QTestMessage * possible_reply = send_msg_replies.at(i); - if (possible_reply && possible_reply->m_msg_id == msg.m_msg_id) { - - reply = *possible_reply; - delete send_msg_replies.takeAt( i ); - - if (debug_on) { - qDebug() << ( QString("%1 QTestProtocol::sendMessage(%2) ... reply received"). - arg(uniqueId()). - arg(message.event()).toLatin1()); - } - - onReplyReceived(&reply); - return true; - } - } - } - } - } - if (state() != ConnectedState) { - reply["status"] = "ERROR: Connection lost. This is likely caused by a crash in the Application Under Test."; - reply["_q_inResponseTo"] = QString("%1\n%2").arg(message.event()).arg(message.toString()); - } else { - qDebug() << "ERROR-REPLY-TIMEOUT: " << t1.elapsed()/*msecsSinceReference()*/ << t2.elapsed()/*msecsSinceReference()*/; - reply["status"] = "ERROR_REPLY_TIMEOUT"; - reply["_q_inResponseTo"] = QString("%1\n%2").arg(message.event()).arg(message.toString()); - } - reply["location"] = QString("%1:%2").arg(__FILE__).arg(__LINE__); - } else { - reply["status"] = "ERROR_NO_CONNECTION"; - reply["_q_inResponseTo"] = QString("%1\n%2").arg(message.event()).arg(message.toString()); - reply["location"] = QString("%1:%2").arg(__FILE__).arg(__LINE__); - } - - if (debug_on) { - qDebug() << ( QString("%1 QTestProtocol::sendMessage(%2) ... done. Status: %3"). - arg(uniqueId()). - arg(message.event()).arg(reply["status"].toString()).toLatin1()); - } - - return false; -} - -/*! - Send the string \a result as a reply to \a originalMsg. -*/ - -void QTestProtocol::replyMessage( QTestMessage *originalMsg, QTestMessage const &message ) -{ - if (debug_on) { - qDebug() << ( QString("%1 QTestProtocol::replyMessage(%2)"). - arg(uniqueId()). - arg(originalMsg->event()).toLatin1()); - } - - QTestMessage msg(message); - msg.m_msg_id = originalMsg->msgId(); - msg.m_event = "@REPLY@"; - send( msg ); -} - -bool QTestProtocol::lastDataReceived() -{ - return last_data_received; -} - -QString QTestProtocol::errorStr() -{ - QString S = "Connection error: "; - switch (error()) { - case ConnectionRefusedError: S += "A connection attempt was rejected by the peer"; break; - case HostNotFoundError: S += "Host not found"; break; - case RemoteHostClosedError: S += "RemoteHostClosedError"; break; - case SocketAccessError: S += "SocketAccessError"; break; - case SocketResourceError: S += "SocketResourceError"; break; - case SocketTimeoutError: S += "SocketTimeoutError"; break; - case DatagramTooLargeError: S += "DatagramTooLargeError"; break; - case NetworkError: S += "NetworkError"; break; - case AddressInUseError: S += "AddressInUseError"; break; - case SocketAddressNotAvailableError: S += "SocketAddressNotAvailableError"; break; - case UnsupportedSocketOperationError: S += "UnsupportedSocketOperationError"; break; - case UnknownSocketError: S += "UnknownSocketError"; break; - default: S += " Unknown error"; - } - - return S; -} - -void QTestProtocol::onConnectionFailed( const QString &reason ) -{ - emit connectionFailed( this, reason ); -} - -void QTestProtocol::testConnection() -{ - if (debug_on) { - qDebug() << QString("%1 QTestProtocol::testConnection()").arg(uniqueId()).toLatin1(); - } - - while (send_msg_replies.count() > 0) - delete send_msg_replies.takeFirst(); - - enablePing( true ); - postMessage( QTestMessage("QTEST_NEW_CONNECTION") ); -} - -void QTestProtocol::send( QTestMessage const &message ) -{ - QByteArray data; - if (!message.m_map.isEmpty()) { - QDataStream s(&data, QIODevice::WriteOnly); - s << message.m_map; - } - - QDataStream tmp(this); - sendPreamble( &tmp, message.msgId(), message.event() ); - - quint32 len = data.count(); - tmp << len; // phase 2 - if (len > 0) { - tmp.writeRawData( data.data(), (int)len ); // phase 3 - } - - tmp << TEST_MSG_END; // phase 4 - - flush(); // Force socket to send data now -} - -void QTestProtocol::sendPreamble( QDataStream *ds, quint16 msgId, const QString &event ) -{ - quint32 len; - *ds << TEST_MSG_SIGNATURE; // phase 0 - *ds << TEST_MSG_VERSION; - *ds << msgId; - - len = (event.length() *2) + 4; - *ds << len; - *ds << event; // phase 1 -} - -bool QTestProtocol::receive( QTestMessage *msg, bool &syncError ) -{ - syncError = false; - - QDataStream stream(this); - - quint8 rx_version; - if (msg->m_phase == uint(0)) { - msg->m_len = 0; - quint32 sig; - if (bytesAvailable() >= sizeof( sig ) + sizeof( rx_version ) + sizeof( msg->m_msg_id ) + sizeof( msg->m_len )) { - stream >> sig; - if (sig != TEST_MSG_SIGNATURE) { - qWarning( QString("QTestMessage::receive(), Invalid start signature (0x%1)").arg(sig,8,16).toLatin1() ); - syncError = true; - return false; - } else { - stream >> rx_version; // FIXME: something should be done to verify the version. - stream >> msg->m_msg_id; - stream >> msg->m_len; - msg->m_phase++; - } - } - } - - if (msg->m_phase == uint(1)) { - if (bytesAvailable() >= msg->m_len) { - stream >> msg->m_event; - msg->m_phase++; - } - } - - if (msg->m_phase == uint(2)) { - if (bytesAvailable() >= sizeof( msg->m_len )) { - stream >> msg->m_len; - msg->m_phase++; - } - } - - if (msg->m_phase == uint(3)) { - if (msg->m_len > 0) { - QByteArray buf; - quint32 len = msg->m_len; - uint bytes_available = bytesAvailable(); - if (bytes_available < len) - len = bytes_available; - buf.resize( len ); - stream.readRawData( buf.data(), len ); - - static QMap<QTestMessage*, QByteArray> data; - data[msg].append(buf); - - msg->m_len -= len; - if (msg->m_len == 0) { - QDataStream s(&data[msg], QIODevice::ReadOnly); - s >> msg->m_map; - data.remove(msg); - msg->m_phase++; - // received OK - } else { - // waiting for more data - return false; - } - } else { - msg->m_phase++; - } - } - - if (msg->m_phase == uint(4)) { - quint32 id2; - if (bytesAvailable() >= sizeof( id2 )) { - stream >> id2; - msg->m_phase = 0; - if (id2 != TEST_MSG_END) { - qWarning( QString("QTestMessage::receive(), Invalid end signature (0x%2)").arg(id2,8,16).toLatin1() ); - syncError = true; - return false; - } else { - return true; - } - } - } - - return false; -} - -bool QTestProtocol::rxBusy() -{ - return rx_busy; -} - -/*! - Reads the remote control connection and responds to received commands. -*/ - -void QTestProtocol::onData() -{ - if (onData_busy) return; - onData_busy = true; - - int sync_error_count = 0; - bool msg_received = true; - while (msg_received && bytesAvailable() > 0) { - msg_received = false; - // set the time to now :-) - rx_timer.start(); - ping_timeout_warning_issued = false; - - bool sync_error; - if (cur_message == 0) - cur_message = new QTestMessage(); - - if (receive( cur_message, sync_error )) { - msg_received = true; - QString last_event = cur_message->event(); - - if (debug_on) { - qDebug() << ( QString("%1 QTestProtocol::onData(%2) msgid = %3"). - arg(uniqueId()). - arg(last_event). - arg(cur_message->m_msg_id). - toLatin1()); - } - - // We received a full message - if (last_event == "@REPLY@") { - send_msg_replies.append( cur_message ); // add the reply to a list - int id = cur_message->m_msg_id; - QTestMessage *received_message(cur_message); - cur_message = 0; // and make sure we create a new one - emit replyReceived( id, received_message ); - } else if (last_event == "QTEST_NEW_CONNECTION") { - postMessage( QTestMessage("QTEST_ACK_CONNECTION") ); // Acknowledge the other side we can receive data - } else if (last_event == "QTEST_ACK_CONNECTION") { - connection_valid = true; // we don't assume we have a connection until both sides have actually received data from the other side - onConnected(); - connect_timer.stop(); - } else if (last_event == "QTEST_CLOSING_CONNECTION") { - last_data_received = true; - QTimer::singleShot( 0, this, SLOT(onSocketClosed())); - } else if (last_event == "PONG") { - // Do nothing - } else if (last_event == "TEST") { - if (!debug_on) { - // don't show the same information twice - qDebug() << QString("%1 Test message received").arg(uniqueId()).toLatin1(); - } - } else if (last_event == "PING") { - postMessage( QTestMessage("PONG") ); - } else { - unhandled_msg.append( cur_message ); // add the msg to a list - cur_message = 0; - QTimer::singleShot(0,this,SLOT(processMessages())); - } - - delete cur_message; - cur_message = 0; - } else { - // We didn't receive a full message - if (sync_error) { - sync_error_count++; - if (sync_error_count > 10) - return; - // receiving garbage messages - nothing can be done but closing the connection and try again. - delete cur_message; - cur_message = 0; - disconnect(!enable_reconnect); - reconnect(); - } - // else we are waiting on more fragments to arrive - } - } - onData_busy = false; -} - -void QTestProtocol::processMessages() -{ - while (!rx_busy && unhandled_msg.count() > 0) { - QTestMessage *tmp = unhandled_msg.takeFirst(); - if (tmp) { - rx_busy = true; - processMessage( tmp ); - delete tmp; - rx_busy = false; - } - } -} - -/*! - Signals the instance that the other side has closed the connection. -*/ -void QTestProtocol::onSocketClosed() -{ - if (debug_on) { - qDebug() << QString("%1 QTestProtocol::onSocketClosed()").arg(uniqueId()).toLatin1(); - } - - // we can't send any more messages so disable pinging - enablePing( false ); - - // anything that is still in the tx buffer gets lost - abort(); - - close(); - - connection_valid = false; - - // if the close was spontaneous and we want to keep the connection alive, we try to reconnect - if (enable_reconnect) { - if (debug_on) { - qDebug() << - QString("%1 QTestProtocol::onSocketClosed() singleshot reconnect in .5 seconds").arg(uniqueId()).toLatin1(); - } - QTimer::singleShot(500,this,SLOT(reconnect())); - } - - // tell the world we are closed - QTimer::singleShot(0, this, SLOT(emitConnectionClosed())); -} - -/*! - Signals the instance that a connection is established with a remote control host. -*/ -void QTestProtocol::onSocketConnected() -{ - connect_timer.stop(); - if (debug_on) { - qDebug() << QString("%1 QTestProtocol::onSocketConnected()").arg(uniqueId()).toLatin1(); - } - testConnection(); -} - -void QTestProtocol::reconnect() -{ - if (host != "" && state() != ConnectedState) { - if (debug_on) { - qDebug() << QString("%1 QTestProtocol::reconnect()").arg(uniqueId()).toLatin1(); - } - - connect_timer.stop(); - connect_timer.start( CONNECT_TIMEOUT ); - - // if we are trying to connect to the local machine, always use 127.0.0.1 - // (and avoid the need for dns) - QString hostname = QHostInfo::localHostName().toUpper(); - if (hostname == host.toUpper() || hostname.startsWith( host.toUpper() + "." )) - host = "127.0.0.1"; - - close(); - connectToHost( host, port ); - } else { - if (host == "") { - qWarning( "QTestProtocol::reconnect() FAILED, no host specified" ); - enable_reconnect = false; - } - } -} - -void QTestProtocol::connectTimeout() -{ - if (debug_on) { - qDebug() << QString("%1 QTestProtocol::connectTimeout()").arg(uniqueId()).toLatin1(); - } - - connect_timer.stop(); - if (enable_reconnect) { - reconnect(); - } else { - onConnectionFailed( errorStr() ); - } -} - -void QTestProtocol::pingTimeout() -{ - if (!ping_enabled) return; - - if (state() == ConnectedState) { -// int elapsed = rx_timer.msecsSinceReference(); - int elapsed = rx_timer.elapsed(); - if (state() == ClosingState) { - if (elapsed > 30000) { // no activity for x seconds when we are closing? - enablePing( false ); - if (enable_reconnect) { - disconnect(); - // close has reset the enable_reconnect value, so enable it again - enableReconnect( true, reconnect_interval ); - reconnect(); - } else { - disconnect(); - } - } else if (elapsed > 2000 ) { - postMessage( QTestMessage("PING") ); - } - } else { - if (elapsed > 10000) { - postMessage( QTestMessage("PING") ); - if (elapsed > 300000) { // no activity for 5 minutes in 'normal' cases?? - if (!ping_timeout_warning_issued) - qWarning( QString("%1 QTestProtocol::pingTimeout() WARNING: Did not receive a msg for %2 ms").arg(uniqueId()).arg(elapsed).toLatin1() ); - ping_timeout_warning_issued = true; - } - } - } - } else { - if (enable_reconnect) { - // Connection seems to be closed, try to reconnect - disconnect(); - - // disconnect has reset the enable_reconnect value, so enable it again - enableReconnect( true, reconnect_interval ); - reconnect(); - } - } -} - -void QTestProtocol::emitConnectionClosed() -{ - if (debug_on) { - qDebug() << ( QString("%1 QTestProtocol::emitConnectionClosed()").arg(uniqueId()).toLatin1()); - } - - emit replyReceived(); // force sendMessage to quit - emit connectionClosed( this ); -} - -void QTestProtocol::enablePing( bool enable ) -{ - if (ping_enabled != enable) { - ping_timer.stop(); - ping_enabled = enable; - if (enable) { - QObject::connect( &ping_timer, SIGNAL(timeout()), this, SLOT(pingTimeout()), Qt::DirectConnection ); - ping_timer.start( ping_interval ); - } else { - QObject::disconnect( &ping_timer, SIGNAL(timeout()), this, SLOT(pingTimeout()) ); - } - } -} - -QString QTestProtocol::uniqueId() -{ - return QString("%1 %2").arg(unique_id).arg(qApp->applicationName()); -} - -void QTestProtocol::enableDebug( bool debugOn ) -{ - debug_on = debugOn; - qDebug() << QString("Debugging is switched %1 for Test Protocol %2").arg(debugOn ? "ON" : "OFF").arg(uniqueId()).toLatin1() ; -} - -void QTestProtocol::disableDebug() -{ - debug_on = false; - qDebug() << QString("Debugging is switched %1 for Test Protocol %2").arg(debug_on ? "ON" : "OFF").arg(uniqueId()).toLatin1() ; -} - diff --git a/libqsystemtest/qtestprotocol_p.h b/libqsystemtest/qtestprotocol_p.h deleted file mode 100644 index 0fcd582..0000000 --- a/libqsystemtest/qtestprotocol_p.h +++ /dev/null @@ -1,208 +0,0 @@ -/************************************************************************** -** -** This file is part of Qt Creator -** -** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). -** -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** Commercial Usage -** -** Licensees holding valid Qt Commercial licenses may use this file in -** accordance with the Qt Commercial License Agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Nokia. -** -** GNU Lesser General Public License Usage -** -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. -** -**************************************************************************/ - -#ifndef QTESTPROTOCOL_P_H -#define QTESTPROTOCOL_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the QtUiTest API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QTimer> -#include <QTime> -#include <QObject> -#include <QString> -#include <QFile> -#include <QVariant> -#include <QMap> -#include <QtNetwork/QTcpSocket> -#include <QtNetwork/QTcpServer> -#include <QtCore/QElapsedTimer> -#include "qtuitestglobal.h" - -#define REMOTE_CONNECT_ERROR 99 - -class QSYSTEMTEST_EXPORT QTestMessage -{ -public: - QTestMessage(QString const &event = QString(), QVariantMap const &map = QVariantMap() ); - QTestMessage(QString const &event, const QTestMessage &other ); - QTestMessage(QString const &event, QString const &queryApp, QString const &queryPath = QString() ); - QTestMessage(const QTestMessage &other); - virtual ~QTestMessage(); - - QTestMessage& operator=(const QTestMessage &other); - - QString event() const; - quint16 msgId() const; - - QVariant const operator[](QString const &key) const; - QVariant &operator[](QString const &key); - bool contains(QString const &key) const; - QList<QString> keys() const; - - QString toString() const; - QVariantMap toMap() const; - - bool statusOK() const; - bool isNull() const; - -protected: - uint m_phase; - quint32 m_len; - - quint16 m_msg_id; - QString m_event; - - QVariantMap m_map; - - friend class QTestProtocol; -}; -Q_DECLARE_METATYPE( QTestMessage ) -Q_DECLARE_METATYPE( QTestMessage* ) -Q_DECLARE_METATYPE( const QTestMessage* ) - -class QTestServerSocket : public QTcpServer -{ - Q_OBJECT -public: - QTestServerSocket( quint16 port, int backlog = 1 ); - virtual ~QTestServerSocket(); - - bool ok() const; - quint16 port() const; - QString address() const; - - virtual void onNewConnection( int socket ) = 0; - -private: - virtual void incomingConnection( int socket ); -}; - -class QTestProtocol : public QTcpSocket -{ - Q_OBJECT -public: - - QTestProtocol(); - virtual ~QTestProtocol(); - - virtual void setSocket( int socket ); - - void enableReconnect( bool enable, uint reconnectInterval = 5000 ); - - void connect( const QString& hostname, int port ); - void disconnect( bool disableReconnect = true ); - bool isConnected(); - virtual bool waitForConnected( int timeout = 10000 ); - - virtual uint postMessage( QTestMessage const &message ); - - virtual bool sendMessage( QTestMessage const &message, QTestMessage &reply, int timeout ); - virtual void replyMessage( QTestMessage *originalMsg, QTestMessage const &message ); - - bool lastDataReceived(); - bool rxBusy(); - virtual void onReplyReceived( QTestMessage *reply ); - - QString errorStr(); - - virtual void onConnectionFailed( const QString &reason ); - virtual void onConnected() {}; // re-implement in derived class - - QString uniqueId(); - void enableDebug( bool debugOn ); - -public slots: - void reconnect(); - void disableDebug(); - -protected: - virtual void processMessage( QTestMessage *msg ) = 0; - - void send( QTestMessage const &message ); - static void sendPreamble( QDataStream *ds, quint16 msgId, const QString &event ); - - bool receive( QTestMessage *msg, bool &syncError ); - -signals: - void connectionClosed( QTestProtocol *socket ); - void connectionFailed( QTestProtocol *socket, const QString &reason ); - void replyReceived(int id = -1, QTestMessage const *message = 0); - void replyConfirmed(); - -protected slots: - void onData(); - void onSocketConnected(); - void onSocketClosed(); - void connectTimeout(); - void pingTimeout(); - void emitConnectionClosed(); - void processMessages(); - void testConnection(); - -private: - void enablePing( bool enable ); - - quint16 tx_msg_id; - QString host; - int port; - bool onData_busy; - bool enable_reconnect; - uint reconnect_interval; - QTimer connect_timer; -// QElapsedTimer rx_timer; - QTime rx_timer; - bool last_data_received; - bool rx_busy; - bool connection_valid; - - QList<QTestMessage*> send_msg_replies; - QList<QTestMessage*> unhandled_msg; - QTestMessage *cur_message; - - bool ping_enabled; - uint ping_interval; - QTimer ping_timer; - uint ping_count; - bool ping_timeout_warning_issued; - QString last_send_cmd; - QString unique_id; - bool debug_on; -}; - -#endif - diff --git a/libqsystemtest/qtestremote.cpp b/libqsystemtest/qtestremote.cpp deleted file mode 100644 index 8aae353..0000000 --- a/libqsystemtest/qtestremote.cpp +++ /dev/null @@ -1,81 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of QtUiTest. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qtestremote_p.h" - -#include <stdlib.h> // used for exit - -QTestRemote::QTestRemote() -{ - must_stop_event_recording = false; - event_recording_aborted = false; -} - -QTestRemote::~QTestRemote() -{ -} - -void QTestRemote::processMessage( QTestMessage *msg ) -{ - if (msg->event() == "stopEventRecording") { - must_stop_event_recording = true; - } else if (msg->event() == "eventRecordingAborted") { - must_stop_event_recording = true; - event_recording_aborted = true; - } else if (msg->event() == "abort") { - emit abort(); - } -} - -/*! - \internal - Opens a socket connection to a remote test tool and uses the connection to - communicate with the connected tool. -*/ -void QTestRemote::openRemote( const QString &ip, int port ) -{ - connect( ip, port ); - if (!waitForConnected(5000)) { - // it really doesn't make sense to continue testing if we cannot communicate with the remote tool so we abort immediately. - exit( REMOTE_CONNECT_ERROR ); - } -} - diff --git a/libqsystemtest/qtestremote_p.h b/libqsystemtest/qtestremote_p.h deleted file mode 100644 index 4d732a6..0000000 --- a/libqsystemtest/qtestremote_p.h +++ /dev/null @@ -1,69 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of QtUiTest. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QTESTREMOTE_P_H -#define QTESTREMOTE_P_H - -#include "qtestprotocol_p.h" -#include "qtuitestglobal.h" - -class QString; - -class QSYSTEMTEST_EXPORT QTestRemote : public QTestProtocol -{ - Q_OBJECT - -public: - QTestRemote(); - virtual ~QTestRemote(); - - void openRemote( const QString &ip, int port ); - virtual void processMessage( QTestMessage *msg ); - - bool must_stop_event_recording; - bool event_recording_aborted; - -signals: - void abort(); -}; - -#endif - diff --git a/libqsystemtest/qtestverifydlg.cpp b/libqsystemtest/qtestverifydlg.cpp deleted file mode 100644 index da4f8fe..0000000 --- a/libqsystemtest/qtestverifydlg.cpp +++ /dev/null @@ -1,174 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of QtUiTest. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qtestverifydlg_p.h" - -#include <QLabel> -#include <QPushButton> -#include <QDesktopWidget> -#include <QLayout> -#include <QPixmap> -#include <QTabWidget> - - -#define WIDTH 364 -#define HEIGHT 310 - -QTestVerifyDlg::QTestVerifyDlg( QWidget* parent ) - : QDialog( parent ) -{ - -// resize( WIDTH, HEIGHT ); - - QVBoxLayout *mainLayout = new QVBoxLayout( this ); - mainLayout->setMargin(11); - mainLayout->setSpacing(6); - - commentLabel = new QLabel(); - commentLabel->setAlignment( Qt::AlignCenter ); - mainLayout->addWidget( commentLabel ); - - QHBoxLayout *pixLayout = new QHBoxLayout; - pixLayout->setMargin(0); - pixLayout->setSpacing(6); - - tabWidget = new QTabWidget(); - tabWidget->setTabPosition( QTabWidget::South ); - - pixLayout->addItem( new QSpacerItem( 12, 12, QSizePolicy::Expanding, QSizePolicy::Minimum ) ); - pixLayout->addWidget( tabWidget ); - pixLayout->addItem( new QSpacerItem( 12, 12, QSizePolicy::Expanding, QSizePolicy::Minimum ) ); - mainLayout->addLayout( pixLayout ); - mainLayout->addItem( new QSpacerItem( 16, 16, QSizePolicy::Expanding, QSizePolicy::Minimum ) ); - QHBoxLayout *buttonLayout = new QHBoxLayout; - buttonLayout->setMargin(0); - buttonLayout->setSpacing(6); - okButton = new QPushButton(); - buttonLayout->addWidget( okButton ); - cancelButton = new QPushButton(); - buttonLayout->addWidget( cancelButton ); - buttonLayout->addItem( new QSpacerItem( 16, 16, QSizePolicy::Expanding, QSizePolicy::Minimum ) ); - mainLayout->addLayout( buttonLayout ); - - // signals and slots connections - connect( okButton, SIGNAL(clicked()), this, SLOT(accept()), Qt::DirectConnection ); - connect( cancelButton, SIGNAL(clicked()), this, SLOT(reject()), Qt::DirectConnection ); - - okButton->setText( "Yes" ); - cancelButton->setText( "No" ); - setWindowTitle( "Verify Pixmap" ); -// questionText = "Does the 'Actual' tab show the correct output?\n "; -// questionLabel->setText(questionText); -} - -/* - Destroys the object and frees any allocated resources -*/ -QTestVerifyDlg::~QTestVerifyDlg() -{ - //hide(); -} - -void QTestVerifyDlg::setComment( const QString &text ) -{ - commentLabel->setText(text); -} - -void QTestVerifyDlg::addTab( const QString &name, const QPixmap &img ) -{ - QLabel *label = new QLabel(); - label->setObjectName( name + "Label" ); - - QSizePolicy sizePolicy = QSizePolicy( QSizePolicy::Preferred, QSizePolicy::Preferred ); - sizePolicy.setHorizontalStretch(0); - sizePolicy.setVerticalStretch(0); - sizePolicy.setHeightForWidth(label->sizePolicy().hasHeightForWidth()); - - label->setSizePolicy( sizePolicy ); - label->setFrameShape( QLabel::Box ); - label->setFrameShadow( QLabel::Sunken ); - label->setScaledContents( false ); - label->setAlignment( Qt::AlignCenter ); - - if (!img.isNull()) { - label->setPixmap(img); - } else { - label->setText("No image available"); - } - - tabWidget->addTab( label, name ); - updateGeometry(); -} -/* -void QTestVerifyDlg::setData( const QPixmap &actual, const QPixmap &expected, - const QPixmap &diff, const QString &comment) -{ - questionLabel->setText(questionText + comment); - if (!actual.isNull()) - actualLabel->setPixmap(actual); - - bool expectedValid = true; - if (!expected.isNull()) { - expectedLabel->setPixmap(expected); - if (!diff.isNull()) { - diffLabel->setPixmap(diff); - } - } - else { - QString S = "No expected pixmap available"; - expectedLabel->setText( S ); - QSize s1 = actualLabel->sizeHint(); - QSize s2 = expectedLabel->sizeHint(); - while (s1.width() > s2.width()) { - S = " " + S + " "; - expectedLabel->setText( S ); - s1 = actualLabel->sizeHint(); - s2 = expectedLabel->sizeHint(); - } - S+="\n\nIf you click on 'Yes' the LEFT pixmap\nwill become the expected pixmap\nand will be used for future comparisons."; - expectedLabel->setText( S ); - - expectedValid = false; - } - - updateGeometry(); -} -*/
\ No newline at end of file diff --git a/libqsystemtest/qtestverifydlg_p.h b/libqsystemtest/qtestverifydlg_p.h deleted file mode 100644 index 529e572..0000000 --- a/libqsystemtest/qtestverifydlg_p.h +++ /dev/null @@ -1,73 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of QtUiTest. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QTESTVERIFYDLG_P_H -#define QTESTVERIFYDLG_P_H - -#include <QDialog> -#include <qtuitestglobal.h> - -class QLabel; -class QPushButton; -class QTabWidget; - -class QSYSTEMTEST_EXPORT QTestVerifyDlg : public QDialog -{ - Q_OBJECT - -public: - QTestVerifyDlg(QWidget* parent = 0); - ~QTestVerifyDlg(); - - void setComment( const QString& ); - void addTab( const QString&, const QPixmap& ); -// void setData( const QPixmap&, const QPixmap&, const QPixmap&, const QString& = QString() ); - -private: - QLabel *commentLabel; - QTabWidget *tabWidget; - QPushButton *okButton; - QPushButton *cancelButton; - -// QString questionText; -}; - -#endif diff --git a/libqsystemtest/qtuitestglobal.h b/libqsystemtest/qtuitestglobal.h deleted file mode 100644 index 497a886..0000000 --- a/libqsystemtest/qtuitestglobal.h +++ /dev/null @@ -1,64 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of QtUiTest. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QTUITEST_GLOBAL_H -#define QTUITEST_GLOBAL_H - -#include <QtGlobal> - -#if defined(Q_OS_WIN32) || defined(Q_OS_SYMBIAN) -# if defined(QSYSTEMTEST_TARGET) -# define QSYSTEMTEST_EXPORT Q_DECL_EXPORT -# else -# define QSYSTEMTEST_EXPORT Q_DECL_IMPORT -# endif -# if defined(QTUITESTRUNNER_TARGET) -# define QTUITESTRUNNER_EXPORT Q_DECL_EXPORT -# else -# define QTUITESTRUNNER_EXPORT Q_DECL_IMPORT -# endif -#else -# define QSYSTEMTEST_EXPORT Q_DECL_EXPORT -# define QTUITESTRUNNER_EXPORT Q_DECL_EXPORT -#endif - -#endif - diff --git a/libqsystemtest/recorddlg.ui b/libqsystemtest/recorddlg.ui deleted file mode 100644 index 3f2178b..0000000 --- a/libqsystemtest/recorddlg.ui +++ /dev/null @@ -1,108 +0,0 @@ -<ui version="4.0" > - <class>RecordDialog</class> - <widget class="QDialog" name="RecordDialog" > - <property name="geometry" > - <rect> - <x>0</x> - <y>0</y> - <width>562</width> - <height>314</height> - </rect> - </property> - <property name="windowTitle" > - <string>System Test</string> - </property> - <layout class="QVBoxLayout" > - <item> - <widget class="QLabel" name="steps_label" > - <property name="text" > - <string>Manual steps to record</string> - </property> - </widget> - </item> - <item> - <widget class="QTextEdit" name="steps_view" > - <property name="readOnly" > - <bool>true</bool> - </property> - </widget> - </item> - <item> - <widget class="QLabel" name="label" > - <property name="text" > - <string>Events are now being recorded and scripting code will be added to the field below. When you have finished recording events, copy the text from the field and click 'Stop'.</string> - </property> - <property name="wordWrap" > - <bool>true</bool> - </property> - </widget> - </item> - <item> - <widget class="QTextEdit" name="codeEdit" > - <property name="font" > - <font> - <family>Courier New</family> - <pointsize>10</pointsize> - </font> - </property> - <property name="readOnly" > - <bool>true</bool> - </property> - <property name="acceptRichText" > - <bool>false</bool> - </property> - </widget> - </item> - <item> - <layout class="QHBoxLayout" > - <item> - <widget class="QPushButton" name="abort_button" > - <property name="text" > - <string>Abort</string> - </property> - </widget> - </item> - <item> - <spacer> - <property name="orientation" > - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" > - <size> - <width>371</width> - <height>26</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QPushButton" name="stopButton" > - <property name="text" > - <string>Stop</string> - </property> - </widget> - </item> - </layout> - </item> - </layout> - </widget> - <resources/> - <connections> - <connection> - <sender>stopButton</sender> - <signal>clicked()</signal> - <receiver>RecordDialog</receiver> - <slot>accept()</slot> - <hints> - <hint type="sourcelabel" > - <x>504</x> - <y>291</y> - </hint> - <hint type="destinationlabel" > - <x>419</x> - <y>295</y> - </hint> - </hints> - </connection> - </connections> -</ui> diff --git a/libqsystemtest/recordevent_p.h b/libqsystemtest/recordevent_p.h deleted file mode 100644 index f8ad42a..0000000 --- a/libqsystemtest/recordevent_p.h +++ /dev/null @@ -1,135 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of QtUiTest. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef RECORDEVENT_P_H -#define RECORDEVENT_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the QtUiTest API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QString> -#include <QVariant> - -struct RecordEvent { - enum Type { - GotFocus, - Entered, - Selected, - Activated, - CheckStateChanged, - TitleChanged, - MessageBoxShown - }; - Type type; - QString widget; - QString focusWidget; - QVariant data; -}; - -#define Q_DECLARE_METATYPE_STREAM(TYPE) \ - QT_BEGIN_NAMESPACE \ - template <> \ - struct QMetaTypeId< TYPE > \ - { \ - enum { Defined = 1 }; \ - static int qt_metatype_id() \ - { \ - static QBasicAtomicInt metatype_id = Q_BASIC_ATOMIC_INITIALIZER(0); \ - if (!metatype_id) { \ - metatype_id = qRegisterMetaType< TYPE >(#TYPE, \ - reinterpret_cast< TYPE *>(quintptr(-1))); \ - qRegisterMetaTypeStreamOperators< TYPE >(#TYPE); \ - } \ - return metatype_id; \ - } \ - }; \ - QT_END_NAMESPACE - -Q_DECLARE_METATYPE_STREAM(RecordEvent); -Q_DECLARE_METATYPE_STREAM(QList<RecordEvent>); - -inline bool operator==(RecordEvent const& a, RecordEvent const& b) -{ return a.type == b.type && a.widget == b.widget && a.focusWidget == b.focusWidget && a.data == b.data; } - -inline bool operator!=(RecordEvent const& a, RecordEvent const& b) -{ return !(a == b); } - -inline QDataStream &operator<<(QDataStream &out, const RecordEvent &re) -{ return (out << static_cast<int>(re.type) << re.widget << re.focusWidget << re.data); } - -inline QDataStream &operator>>(QDataStream &in, RecordEvent &re) -{ - int reType; - QDataStream &ret = (in >> reType >> re.widget >> re.focusWidget >> re.data); - re.type = static_cast<RecordEvent::Type>(reType); - return ret; -} - -inline QDataStream &operator<<(QDataStream &out, const QList<RecordEvent> &l) -{ - out << l.count(); - foreach (RecordEvent re, l) { - out << re; - } - return out; -} -inline QDataStream &operator>>(QDataStream &in, QList<RecordEvent> &l) -{ - int count = 0; - in >> count; - RecordEvent re; - for (int i = 0; i < count; ++i) { - in >> re; - l << re; - } - return in; -} - -#endif - diff --git a/libqsystemtest/symbiantestcontrol.cpp b/libqsystemtest/symbiantestcontrol.cpp deleted file mode 100644 index d1586bc..0000000 --- a/libqsystemtest/symbiantestcontrol.cpp +++ /dev/null @@ -1,31 +0,0 @@ -#include "symbiantestcontrol.h" - -using namespace Qt4Test; - -SymbianTestControl::SymbianTestControl() - : TestControl() -{ - -} - -SymbianTestControl::~SymbianTestControl() -{ - -} - -bool SymbianTestControl::deviceConfiguration( QString &reply ) -{ - return false; -} - -bool SymbianTestControl::startApplication( const QString &application, const QStringList &arguments, - bool styleQtUITest, const QStringList &environment, QString &reply ) -{ - return false; -} - -bool SymbianTestControl::killApplication( const QString &application, QString &reply ) -{ - return false; -} - diff --git a/libqsystemtest/symbiantestcontrol.h b/libqsystemtest/symbiantestcontrol.h deleted file mode 100644 index 2b273ab..0000000 --- a/libqsystemtest/symbiantestcontrol.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef SYMBIANTESTCONTROL_H -#define SYMBIANTESTCONTROL_H - -#include "testcontrol.h" - -namespace Qt4Test { -class SymbianTestControl : public TestControl -{ - Q_OBJECT -public: - SymbianTestControl(); - virtual ~SymbianTestControl(); - - bool deviceConfiguration( QString &reply ); - - bool startApplication( const QString &application, const QStringList &arguments, - bool styleQtUITest, const QStringList &environment, QString &reply ); - bool killApplication( const QString &application, QString &reply ); -}; -} - -#endif // SYMBIANTESTCONTROL_H diff --git a/libqsystemtest/testcontrol.cpp b/libqsystemtest/testcontrol.cpp deleted file mode 100644 index 75cf279..0000000 --- a/libqsystemtest/testcontrol.cpp +++ /dev/null @@ -1,145 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of Qt Creator. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "testcontrol.h" -#include "desktoptestcontrol.h" -#include "customtestcontrol.h" -#include "maemotestcontrol.h" -#include "meegotestcontrol.h" -#include "symbiantestcontrol.h" - -#include <QDebug> -#include <QRegExp> -#include <QTime> -#include <QApplication> -#include <QTimer> - -namespace Core { - class SshConnection; - class SshRemoteProcess; -} // namespace Core - -using namespace Core; - -namespace Qt4Test { - -TestControl::TestControl() -{ - -} - -TestControl::~TestControl() -{ - -} - -TestController::TestController( TestDeviceType type, Core::SshConnectionParameters *sshParam ) -{ - if (sshParam) ssh_param = *sshParam; - test_device_type = type; -} - -TestController::~TestController() -{ - killApplications(); - - while (device_controls.count() > 0) - delete device_controls.takeFirst(); -} - -TestControl* TestController::controlFactory() -{ - if (test_device_type == Maemo) - return new MaemoTestControl(ssh_param); -// return MaemoTestControl::instance(ssh_param); - else if (test_device_type == Desktop) -// return new DesktopTestControl(); - return DesktopTestControl::instance(); - else if (test_device_type == MeeGo) - return new MeeGoTestControl(); -// return MeeGoTestControl::instance(); - else if (test_device_type == Custom) - return new CustomTestControl(); -// return CustomTestControl::instance(); - else if (test_device_type == Symbian) - return new SymbianTestControl(); -// return SymbianTestControl::instance(); - return 0; -} - -bool TestController::deviceConfiguration( QString &reply ) -{ - TestControl *ctrl = controlFactory(); - bool ok = (ctrl && ctrl->deviceConfiguration(reply)); - delete ctrl; - return ok; -} - -bool TestController::startApplication( const QString &application, const QStringList &arguments, - bool styleQtUITest, const QStringList &environment, QString &reply ) -{ - TestControl *ctrl = controlFactory(); - if (ctrl) { -// device_controls.append(ctrl); - if (ctrl->startApplication(application, arguments, styleQtUITest, environment, reply)) { - started_applications += application; - return true; - } - } - return false; -} - -bool TestController::killApplication( const QString &application, QString &reply ) -{ - TestControl *ctrl = controlFactory(); - if (ctrl) { -// device_controls.append(ctrl); - return ctrl->killApplication(application, reply); - } - return false; -} - -void TestController::killApplications() -{ - if (started_applications.count() == 0) - return; - - QString reply; - foreach (QString app, started_applications) { - killApplication(app, reply); - } - started_applications.clear(); -} - -} // namespace Qt4Test diff --git a/libqsystemtest/testcontrol.h b/libqsystemtest/testcontrol.h deleted file mode 100644 index fba2e89..0000000 --- a/libqsystemtest/testcontrol.h +++ /dev/null @@ -1,93 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of Qt Creator. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef TESTCONTROL_H -#define TESTCONTROL_H - -#include <coreplugin/ssh/sshconnection.h> - -#include <QtCore/QSharedPointer> -#include <QHash> -#include <QStringList> - -namespace Qt4Test { - -class TestControl : public QObject -{ - Q_OBJECT -public: - TestControl(); - virtual ~TestControl(); - - virtual bool deviceConfiguration( QString &reply ) = 0; - virtual bool startApplication( const QString &application, const QStringList &arguments, - bool styleQtUITest, const QStringList &environment, QString &reply ) = 0; - virtual bool killApplication( const QString &application, QString &reply ) = 0; -}; - -/** - * A class that can communicate with a device, using a secure connection. - */ -class TestController : public QObject -{ - Q_OBJECT -public: - enum TestDeviceType {Desktop, Maemo, MeeGo, Custom, Symbian}; - TestController( TestDeviceType type, Core::SshConnectionParameters *sshParam = 0 ); - virtual ~TestController(); - - enum TestControlMode {Idle, ConfigCheck, CustomCommand, CustomBlockingCommand}; - - bool deviceConfiguration( QString &reply ); - - bool startApplication( const QString &application, const QStringList &arguments, - bool styleQtUITest, const QStringList &environment, QString &reply ); - bool killApplication( const QString &application, QString &reply ); - void killApplications(); - -protected: - Core::SshConnectionParameters ssh_param; - TestDeviceType test_device_type; - - TestControl* controlFactory(); - -private: - QList<TestControl*> device_controls; - QStringList started_applications; -}; - - -} // namespace Qt4Test - -#endif // TESTCONTROL_H |
