diff --git a/tools/chatgui/tests/test_stream_publish.cpp b/tools/chatgui/tests/test_stream_publish.cpp index b002e9fc..ddf73fe7 100644 --- a/tools/chatgui/tests/test_stream_publish.cpp +++ b/tools/chatgui/tests/test_stream_publish.cpp @@ -887,6 +887,42 @@ private slots: QSKIP("Capture fixture unavailable"); #endif } + void controlsEscapeKeepsPublication() { +#if defined(HAVE_STREAM_CAPTURE) && defined(TEST_NULL_AUDIO) + if (!qEnvironmentVariableIsSet("UTUN_TEST_SCREEN_CAPTURE")) QSKIP("Run under isolated Xvfb"); + QVERIFY(SoundManager::instance()->init()); + QLabel pattern("Publisher controls fixture"); pattern.resize(320, 180); pattern.show(); + StreamPublishEngine engine; QTRY_VERIFY_WITH_TIMEOUT(!engine.codecs().isEmpty(), 15000); + connect(&engine, &StreamPublishEngine::softwareEncodingRequested, &engine, + [&engine](uint64_t generation) { engine.answerSoftwareEncoding(generation, true); }); + StreamPublishConfig config; config.audio = false; config.video.width = 640; config.video.height = 360; config.video.fps = 15; + for (const auto& source : engine.sources()) if (source.kind == StreamVideoSource::Screen) { config.source = source; break; } + QVERIFY(!config.source.id.isEmpty()); QVERIFY(engine.start(group, config)); + stream_member_state before{}; + QTRY_VERIFY_WITH_TIMEOUT(stream_member_load(inst, group, inst->node_id, &before, nullptr) == STREAM_OK && before.published, 5000); + QVERIFY(gui_stream_open(205, group, inst->node_id, before.source.source_epoch)); + StreamRecord out; QVERIFY(record(205, StreamRecordKind::Opened, out)); QVERIFY(record(205, StreamRecordKind::Video, out)); + const uint64_t firstPts = out.pts; + StreamPublishWindow controls(&engine, group); controls.show(); controls.activateWindow(); + QVERIFY(QTest::qWaitForWindowActive(&controls)); + auto* preview = controls.findChild(); QVERIFY(preview); + QTRY_VERIFY(preview->videoSink()->videoFrame().isValid()); + QSignalSpy closed(&controls, &StreamPublishWindow::closed); + auto* choice = controls.findChild(); QVERIFY(choice); choice->setFocus(); + QTest::keyClick(choice, Qt::Key_Escape); + QTRY_COMPARE(closed.count(), 1); QVERIFY(!controls.isVisible()); QVERIFY(engine.running()); + QVERIFY(record(205, StreamRecordKind::Video, out)); QVERIFY(out.pts > firstPts); + stream_member_state after{}; + QCOMPARE(stream_member_load(inst, group, inst->node_id, &after, nullptr), STREAM_OK); + QCOMPARE(after.source.source_epoch, before.source.source_epoch); QVERIFY(after.published); + DEBUG_INFO(DEBUG_CATEGORY_STREAM, "fixture publisher controls Esc: epoch=%llx video_PTS=%llu->%llu running=1", + (unsigned long long)after.source.source_epoch, (unsigned long long)firstPts, (unsigned long long)out.pts); + gui_stream_stop(205); engine.stop(); QTRY_VERIFY_WITH_TIMEOUT(!engine.active(), 4000); +#else + QSKIP("Publisher controls fixture requires Qt Multimedia and null audio"); +#endif + } + void screenAndWindowCapture() { #if defined(HAVE_STREAM_CAPTURE) && defined(TEST_NULL_AUDIO) if (!qEnvironmentVariableIsSet("UTUN_TEST_SCREEN_CAPTURE")) QSKIP("Real screen/window capture runs separately under Xvfb"); diff --git a/tools/chatgui/tests/test_stream_view.cpp b/tools/chatgui/tests/test_stream_view.cpp index 339ef248..f97f70b4 100644 --- a/tools/chatgui/tests/test_stream_view.cpp +++ b/tools/chatgui/tests/test_stream_view.cpp @@ -514,10 +514,9 @@ private slots: QSignalSpy manage(&grid, &StreamGridWindow::publishRequested); QTest::mouseClick(preview, Qt::LeftButton); QTRY_COMPARE(manage.count(), 1); QCOMPARE(manage.at(0).at(0).toULongLong(), group); QCOMPARE(grid.focusedSource(), uint64_t(0)); - auto nativeWindows = preview->findChildren(); - DEBUG_INFO(DEBUG_CATEGORY_STREAM, "fixture local preview native_windows=%lld", (long long)nativeWindows.size()); - QVERIFY(!nativeWindows.isEmpty()); - QTest::mouseClick(nativeWindows.first(), Qt::LeftButton); QTRY_COMPARE(manage.count(), 2); + QVERIFY(grid.windowHandle()); + QTest::mouseClick(grid.windowHandle(), Qt::LeftButton, Qt::NoModifier, preview->mapTo(&grid, preview->rect().center())); + QTRY_COMPARE(manage.count(), 2); // Доставка через нативное окно, включая внутренний QWidget поверхности Qt. snapshot(true); QPointer remote = grid.findChild(); QVERIFY(remote); auto* video = remote->findChild(); QVERIFY(video);