Files
galeon 5635dcc558
tests / package-smoke-linux (push) Skipped
tests / package-smoke-windows (push) Skipped
tests / macos (push) Successful in 1m22s
tests / linux (pull_request) Successful in 1m54s
tests / package-smoke-macos (push) Skipped
tests / linux (push) Successful in 2m43s
tests / windows (push) Successful in 4m13s
tests / windows (pull_request) Skipped
tests / macos (pull_request) Skipped
tests / package-smoke-linux (pull_request) Skipped
tests / package-smoke-windows (pull_request) Skipped
tests / package-smoke-macos (pull_request) Skipped
autotests fixes
Signed-off-by: galeon <dertiellis@gmail.com>
2026-11-01 21:07:03 +03:00

110 lines
4.8 KiB
C++

// Дымовой тест главного окна: Main.qml поднимается так же, как в main.cpp,
// без единого предупреждения QML, и ни одного запроса в настоящую сеть.
// Ловит то, что не видно компилятору: опечатки в именах свойств и ключах Loc.t,
// сломанные биндинги, несуществующие картинки в ресурсах.
#include "testenv.h"
#include "fakeinternet.h"
#include "fixtures.h"
#include "launcherpaths.h"
#include "localization.h"
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQuickStyle>
#include <QQuickWindow>
#include <QtQml/qqmlextensionplugin.h>
Q_IMPORT_QML_PLUGIN(BiLauncherPlugin)
namespace {
QStringList g_problems;
QtMessageHandler g_previous = nullptr;
void collect(QtMsgType type, const QMessageLogContext &context, const QString &message)
{
// Предупреждения QML приходят с файлом qrc:/… или с категорией qt.qml.*.
const QString file = QString::fromUtf8(context.file ? context.file : "");
const QString category = QString::fromUtf8(context.category ? context.category : "");
const bool fromQml = file.startsWith(QLatin1String("qrc:")) || file.endsWith(QLatin1String(".qml"))
|| category.startsWith(QLatin1String("qt.qml"))
|| message.contains(QLatin1String(".qml:"));
if (type != QtDebugMsg && type != QtInfoMsg && fromQml)
g_problems << message;
if (g_previous)
g_previous(type, context, message);
}
} // namespace
class TestQmlSmoke : public QObject
{
Q_OBJECT
FakeInternet m_net;
private slots:
void initTestCase()
{
QString error;
QVERIFY2(m_net.start(&error), qPrintable(error));
m_net.setFallback(FakeResponse::error(503));
const QString game = TestEnv::freshDir(QStringLiteral("game"));
Fixtures::writeJson(LauncherPaths::settingsFile(), QJsonObject{{"gameDir", game}, {"language", "en"}});
QQuickStyle::setStyle(QStringLiteral("Basic"));
g_previous = qInstallMessageHandler(collect);
}
void cleanupTestCase() { qInstallMessageHandler(g_previous); }
void init() { g_problems.clear(); }
void mainWindowLoadsCleanly()
{
// Один движок на весь тест, как в приложении: Localization держит указатель
// на JS-движок, создавший синглтон, и второй QQmlApplicationEngine после
// уничтожения первого оставил бы его висячим.
QQmlApplicationEngine engine;
QStringList warnings;
connect(&engine, &QQmlEngine::warnings, this, [&](const QList<QQmlError> &list) {
for (const QQmlError &e : list)
warnings << e.toString();
});
engine.loadFromModule("BiLauncher", "Main");
QCOMPARE(engine.rootObjects().size(), 1);
auto *window = qobject_cast<QQuickWindow *>(engine.rootObjects().constFirst());
QVERIFY(window);
QVERIFY(QTest::qWaitForWindowExposed(window));
// Даём отработать отложенным таймерам, загрузке каталогов и анимациям.
QTest::qWait(2500);
QVERIFY2(warnings.isEmpty(), qPrintable(warnings.join(u'\n')));
QVERIFY2(g_problems.isEmpty(), qPrintable(g_problems.join(u'\n')));
// Смена языка на лету перестраивает Loc.t — биндинги не должны ломаться.
const QString titleEn = window->title();
Localization::instance().setLanguage(QStringLiteral("ru"));
QTest::qWait(500);
Localization::instance().setLanguage(QStringLiteral("en"));
QTest::qWait(300);
QCOMPARE(window->title(), titleEn);
QVERIFY2(warnings.isEmpty(), qPrintable(warnings.join(u'\n')));
QVERIFY2(g_problems.isEmpty(), qPrintable(g_problems.join(u'\n')));
// Наружу — только через FakeInternet, и только на известные адреса лаунчера.
static const QStringList known{"mojang.com", "galeonworx.com", "adoptium.net", "fabricmc.net",
"quiltmc.org", "minecraftforge.net", "neoforged.net"};
for (const QString &url : m_net.requestedUrls()) {
const QString host = QUrl(url).host();
const bool ok = std::any_of(known.cbegin(), known.cend(),
[&](const QString &domain) { return host.endsWith(domain); });
QVERIFY2(ok, qPrintable("неожиданный запрос: " + url));
}
}
};
BILAUNCHER_GUI_TEST_MAIN(TestQmlSmoke)
#include "tst_qml_smoke.moc"