a device run can be looked at: --shots, and Qt's messages in the log
The settings dialog check failed only on the phone, with no QML error and nothing to read: this build's Qt messages never reach logcat (verified: a plain qInfo from the app is not in the buffer). Two ways in, then: - --uitest installs a message handler that writes Qt's own warnings into uitest.log, next to the checks. What the phone did say, it says there. - --uitest --shots saves window grabs at the interesting points into the workspace. A device run cannot be handed CST_APP_SHOT (an app started from adb gets no environment), so what a desktop run asks for with an environment variable has to be an argument here. main.cpp takes it, so `--uitest --workspace DIR --shots` works from adb. What they said about the phone (NX789J, 1280x853): ok ... the gear is reachable, centre 1191,56 of 1280x853 ok ... and openSettings() opens it when called directly so the button is there and the handler works: the synthesized click is what does not open the dialog. The run's own picture of that moment shows why -- the header is drawn over the sidebar, so the click lands on what is drawn above the gear. On a desktop the same window has the header above the sidebar and the click lands. Not fixed yet (nor the Open/Share checks on the device, which are the other two failures that are not about the dialog). The settings checks now go on either way, so a phone run reports the dialog instead of eleven lines of "not there".
This commit is contained in:
@@ -193,12 +193,20 @@ int main(int argc, char **argv) {
|
|||||||
QCommandLineOption sizeOpt(QStringLiteral("size"),
|
QCommandLineOption sizeOpt(QStringLiteral("size"),
|
||||||
QStringLiteral("initial window size, e.g. 480x900"),
|
QStringLiteral("initial window size, e.g. 480x900"),
|
||||||
QStringLiteral("WxH"));
|
QStringLiteral("WxH"));
|
||||||
|
/* A device run cannot be handed an environment (see activityArguments()), so
|
||||||
|
* what a desktop run asks for with CST_APP_SHOT=shot.png has to be an
|
||||||
|
* argument here. */
|
||||||
|
QCommandLineOption shotsOpt(
|
||||||
|
QStringLiteral("shots"),
|
||||||
|
QStringLiteral("--uitest: save a picture of the window at the interesting "
|
||||||
|
"points, in the workspace"));
|
||||||
parser.addOption(wsOpt);
|
parser.addOption(wsOpt);
|
||||||
parser.addOption(providerOpt);
|
parser.addOption(providerOpt);
|
||||||
parser.addOption(modelOpt);
|
parser.addOption(modelOpt);
|
||||||
parser.addOption(planOpt);
|
parser.addOption(planOpt);
|
||||||
parser.addOption(uitestOpt);
|
parser.addOption(uitestOpt);
|
||||||
parser.addOption(sizeOpt);
|
parser.addOption(sizeOpt);
|
||||||
|
parser.addOption(shotsOpt);
|
||||||
/* What the process was started with, plus -- on a phone -- what the
|
/* What the process was started with, plus -- on a phone -- what the
|
||||||
* activity was started with: Qt's own applicationArguments plumbing does
|
* activity was started with: Qt's own applicationArguments plumbing does
|
||||||
* not deliver the extra on the NX789J (see activityArguments()), and
|
* not deliver the extra on the NX789J (see activityArguments()), and
|
||||||
@@ -235,6 +243,12 @@ int main(int argc, char **argv) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Before the window exists: maybeShot() reads this at the point a picture is
|
||||||
|
* wanted (the settings dialog, the end of the run). */
|
||||||
|
if (parser.isSet(shotsOpt))
|
||||||
|
qputenv("CST_APP_SHOT",
|
||||||
|
(ws + QStringLiteral("/uitest-shot.png")).toUtf8());
|
||||||
|
|
||||||
#if defined(Q_OS_ANDROID)
|
#if defined(Q_OS_ANDROID)
|
||||||
/* Before the engine is created: its settings, credentials and session store
|
/* Before the engine is created: its settings, credentials and session store
|
||||||
* all resolve their paths from the environment. */
|
* all resolve their paths from the environment. */
|
||||||
|
|||||||
@@ -29,6 +29,7 @@
|
|||||||
#include <QVariantMap>
|
#include <QVariantMap>
|
||||||
|
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
#include <cstdlib>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
@@ -51,6 +52,27 @@ int g_fail;
|
|||||||
* file could not be made, in which case the run only prints. */
|
* file could not be made, in which case the run only prints. */
|
||||||
QFile g_runLog;
|
QFile g_runLog;
|
||||||
|
|
||||||
|
/* Qt's own messages go into the same log as the checks: this is where QML
|
||||||
|
* puts "TypeError: Cannot read property ... of undefined" and every other
|
||||||
|
* reason a step did nothing, and a device run has nowhere else to show it
|
||||||
|
* (logcat does not carry this build's Qt messages -- a plain qInfo from the
|
||||||
|
* app is not in the buffer). Messages before the log is opened still print. */
|
||||||
|
void logQtMessage(QtMsgType type, const QMessageLogContext &, const QString &msg) {
|
||||||
|
const char *kind = type == QtDebugMsg ? "debug"
|
||||||
|
: type == QtInfoMsg ? "info"
|
||||||
|
: type == QtWarningMsg ? "warn"
|
||||||
|
: type == QtCriticalMsg ? "crit"
|
||||||
|
: "fatal";
|
||||||
|
const QByteArray line = QByteArray(kind) + " " + msg.toUtf8() + "\n";
|
||||||
|
if (g_runLog.isOpen()) {
|
||||||
|
g_runLog.write(line);
|
||||||
|
g_runLog.flush();
|
||||||
|
}
|
||||||
|
fwrite(line.constData(), 1, static_cast<size_t>(line.size()), stderr);
|
||||||
|
if (type == QtFatalMsg)
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
void check(bool ok, const QString &what) {
|
void check(bool ok, const QString &what) {
|
||||||
std::printf("%s %s\n", ok ? "ok " : "FAIL", qPrintable(what));
|
std::printf("%s %s\n", ok ? "ok " : "FAIL", qPrintable(what));
|
||||||
std::fflush(stdout);
|
std::fflush(stdout);
|
||||||
@@ -262,6 +284,7 @@ int runUiTest(AgentCore &core, const QString &size) {
|
|||||||
* makes, so a device run can be read back without logcat (see g_runLog). */
|
* makes, so a device run can be read back without logcat (see g_runLog). */
|
||||||
g_runLog.setFileName(core.workspace() + QStringLiteral("/uitest.log"));
|
g_runLog.setFileName(core.workspace() + QStringLiteral("/uitest.log"));
|
||||||
g_runLog.open(QIODevice::WriteOnly | QIODevice::Truncate);
|
g_runLog.open(QIODevice::WriteOnly | QIODevice::Truncate);
|
||||||
|
qInstallMessageHandler(logQtMessage);
|
||||||
const QString resumed =
|
const QString resumed =
|
||||||
writeFixtureSession(core.workspace(), QStringLiteral("20260101-115959-on"));
|
writeFixtureSession(core.workspace(), QStringLiteral("20260101-115959-on"));
|
||||||
check(!resumed.isEmpty() && core.switchSession(resumed),
|
check(!resumed.isEmpty() && core.switchSession(resumed),
|
||||||
@@ -642,6 +665,29 @@ int runUiTest(AgentCore &core, const QString &size) {
|
|||||||
clickMouse(win, QStringLiteral("settingsButton"));
|
clickMouse(win, QStringLiteral("settingsButton"));
|
||||||
QQuickItem *panel = item(win, QStringLiteral("settingsPanel"));
|
QQuickItem *panel = item(win, QStringLiteral("settingsPanel"));
|
||||||
check(panel && panel->isVisible(), QStringLiteral("the gear opens the settings dialog"));
|
check(panel && panel->isVisible(), QStringLiteral("the gear opens the settings dialog"));
|
||||||
|
/* item() answers with an item that exists even when nothing is visible (the
|
||||||
|
* QObject-tree fallback), so "the dialog is not open" is the invisible case
|
||||||
|
* too. */
|
||||||
|
if (!panel || !panel->isVisible()) {
|
||||||
|
/* Two ways to be wrong -- a click that never lands, and a handler that
|
||||||
|
* does nothing -- and from the outside they look the same (this failed
|
||||||
|
* only on the phone, with no QML error at all). Say which, and go on with
|
||||||
|
* the dialog either way, so the checks below still say something. */
|
||||||
|
QQuickItem *gear = item(win, QStringLiteral("settingsButton"));
|
||||||
|
check(gear != nullptr && gear->isVisible(),
|
||||||
|
QStringLiteral("... the gear is %1, centre %2,%3 of %4x%5")
|
||||||
|
.arg(gear && gear->isVisible() ? QStringLiteral("reachable")
|
||||||
|
: QStringLiteral("not there"))
|
||||||
|
.arg(gear ? centre(gear).x() : -1)
|
||||||
|
.arg(gear ? centre(gear).y() : -1)
|
||||||
|
.arg(win->width())
|
||||||
|
.arg(win->height()));
|
||||||
|
QMetaObject::invokeMethod(win, "openSettings");
|
||||||
|
QTest::qWait(120);
|
||||||
|
panel = item(win, QStringLiteral("settingsPanel"));
|
||||||
|
check(panel && panel->isVisible(),
|
||||||
|
QStringLiteral("... and openSettings() opens it when called directly"));
|
||||||
|
}
|
||||||
check(countNamed(win->contentItem(), QStringLiteral("providerRow:")) > 0,
|
check(countNamed(win->contentItem(), QStringLiteral("providerRow:")) > 0,
|
||||||
QStringLiteral("the dialog lists the providers"));
|
QStringLiteral("the dialog lists the providers"));
|
||||||
maybeShot(win, QStringLiteral("-settings"));
|
maybeShot(win, QStringLiteral("-settings"));
|
||||||
|
|||||||
Reference in New Issue
Block a user