add testing and plan milestones
This commit is contained in:
@@ -20,6 +20,8 @@
|
||||
#include "hot_reload.h"
|
||||
#include "desktop_platform.h"
|
||||
#include "testing/ui_inspector.h"
|
||||
#include "testing/action_recorder.h"
|
||||
#include "testing/action_player.h"
|
||||
|
||||
// Command-line options
|
||||
struct Options {
|
||||
@@ -31,6 +33,8 @@ struct Options {
|
||||
std::string output_dir = "dump";
|
||||
std::string log_file; // If set, write logs to this file
|
||||
std::string hierarchy_file; // If set, dump UI hierarchy to this file each frame
|
||||
std::string record_file; // If set, record actions to JSON file
|
||||
std::string playback_file; // If set, play back actions from JSON file
|
||||
};
|
||||
|
||||
// Global log file stream
|
||||
@@ -89,6 +93,43 @@ static mosis::IKernel* g_kernel = nullptr;
|
||||
static std::filesystem::path g_assets_path;
|
||||
static mosis::testing::UIInspector g_ui_inspector;
|
||||
|
||||
// Recording/playback state
|
||||
static std::unique_ptr<mosis::testing::ActionRecorder> g_recorder;
|
||||
static std::unique_ptr<mosis::testing::ActionPlayer> g_player;
|
||||
static std::string g_record_file_path;
|
||||
|
||||
// Key callback for F5 (recording control)
|
||||
bool HandleKeyDown(Rml::Context* context, Rml::Input::KeyIdentifier key, int key_modifier, float native_dp_ratio, bool priority) {
|
||||
// F5: Toggle recording / Save recording
|
||||
if (key == Rml::Input::KI_F5 && g_recorder) {
|
||||
if (g_recorder->IsRecording()) {
|
||||
g_recorder->StopRecording();
|
||||
if (g_recorder->SaveToFile(g_record_file_path)) {
|
||||
LogMessage("Recording saved to: " + g_record_file_path);
|
||||
} else {
|
||||
LogMessage("ERROR: Failed to save recording to: " + g_record_file_path);
|
||||
}
|
||||
} else {
|
||||
g_recorder->StartRecording();
|
||||
LogMessage("Recording started (press F5 to stop and save)");
|
||||
}
|
||||
return true; // Consumed
|
||||
}
|
||||
|
||||
// F6: Pause/resume playback
|
||||
if (key == Rml::Input::KI_F6 && g_player) {
|
||||
if (g_player->IsPlaying()) {
|
||||
g_player->Pause();
|
||||
LogMessage("Playback paused");
|
||||
} else if (g_player->IsPaused()) {
|
||||
g_player->Resume();
|
||||
LogMessage("Playback resumed");
|
||||
}
|
||||
return true; // Consumed
|
||||
}
|
||||
|
||||
return false; // Not consumed, let RmlUi handle it
|
||||
}
|
||||
|
||||
int main(int argc, const char* argv[])
|
||||
{
|
||||
@@ -206,6 +247,25 @@ int main(int argc, const char* argv[])
|
||||
// Start kernel
|
||||
kernel->Start();
|
||||
|
||||
// Initialize recording if enabled
|
||||
if (!opts.record_file.empty()) {
|
||||
g_recorder = std::make_unique<mosis::testing::ActionRecorder>(opts.width, opts.height);
|
||||
g_record_file_path = opts.record_file;
|
||||
LogMessage("Recording mode enabled. Press F5 to start recording.");
|
||||
}
|
||||
|
||||
// Initialize playback if enabled
|
||||
if (!opts.playback_file.empty()) {
|
||||
g_player = std::make_unique<mosis::testing::ActionPlayer>(context);
|
||||
if (g_player->LoadFromFile(opts.playback_file)) {
|
||||
LogMessage("Loaded playback file: " + opts.playback_file);
|
||||
g_player->Start();
|
||||
} else {
|
||||
LogMessage("ERROR: Failed to load playback file: " + opts.playback_file);
|
||||
g_player.reset();
|
||||
}
|
||||
}
|
||||
|
||||
// Setup hot-reload
|
||||
std::unique_ptr<mosis::desktop::HotReload> hot_reload;
|
||||
if (!opts.dump_mode) {
|
||||
@@ -228,8 +288,16 @@ int main(int argc, const char* argv[])
|
||||
hot_reload->CheckForChanges();
|
||||
}
|
||||
|
||||
// Process events and update
|
||||
running = Backend::ProcessEvents(context);
|
||||
// Process events and update (with key callback for F5/F6 control)
|
||||
running = Backend::ProcessEvents(context, HandleKeyDown);
|
||||
|
||||
// Update playback if active
|
||||
if (g_player && g_player->IsPlaying()) {
|
||||
g_player->Update();
|
||||
if (g_player->IsFinished()) {
|
||||
LogMessage("Playback complete");
|
||||
}
|
||||
}
|
||||
|
||||
// Update kernel (processes tasks, updates time, etc.)
|
||||
kernel->Update();
|
||||
@@ -249,6 +317,16 @@ int main(int argc, const char* argv[])
|
||||
}
|
||||
|
||||
// Cleanup
|
||||
// Stop and save recording if still active
|
||||
if (g_recorder && g_recorder->IsRecording()) {
|
||||
g_recorder->StopRecording();
|
||||
if (g_recorder->SaveToFile(g_record_file_path)) {
|
||||
LogMessage("Recording saved on exit to: " + g_record_file_path);
|
||||
}
|
||||
}
|
||||
g_recorder.reset();
|
||||
g_player.reset();
|
||||
|
||||
kernel->Stop();
|
||||
kernel.reset();
|
||||
g_kernel = nullptr;
|
||||
@@ -282,11 +360,19 @@ void PrintUsage(const char* program)
|
||||
std::cout << " --output DIR Output directory for dump mode (default: dump)" << std::endl;
|
||||
std::cout << " --log FILE Write log output to file (for automated testing)" << std::endl;
|
||||
std::cout << " --hierarchy FILE Continuously dump UI hierarchy to JSON file" << std::endl;
|
||||
std::cout << " --record FILE Record actions to JSON file (F5 to start/stop)" << std::endl;
|
||||
std::cout << " --playback FILE Play back recorded actions from JSON file" << std::endl;
|
||||
std::cout << std::endl;
|
||||
std::cout << "Recording Controls:" << std::endl;
|
||||
std::cout << " F5 Start/stop recording (when --record is enabled)" << std::endl;
|
||||
std::cout << " F6 Pause/resume playback (when --playback is enabled)" << std::endl;
|
||||
std::cout << std::endl;
|
||||
std::cout << "Examples:" << std::endl;
|
||||
std::cout << " " << program << " assets/apps/home/home.rml" << std::endl;
|
||||
std::cout << " " << program << " assets/apps/home/home.rml --resolution 720x1280" << std::endl;
|
||||
std::cout << " " << program << " assets/apps/home/home.rml --dump" << std::endl;
|
||||
std::cout << " " << program << " assets/apps/home/home.rml --record test.json" << std::endl;
|
||||
std::cout << " " << program << " assets/apps/home/home.rml --playback test.json" << std::endl;
|
||||
}
|
||||
|
||||
Options ParseOptions(int argc, const char* argv[])
|
||||
@@ -313,6 +399,10 @@ Options ParseOptions(int argc, const char* argv[])
|
||||
opts.log_file = argv[++i];
|
||||
} else if (arg == "--hierarchy" && i + 1 < argc) {
|
||||
opts.hierarchy_file = argv[++i];
|
||||
} else if (arg == "--record" && i + 1 < argc) {
|
||||
opts.record_file = argv[++i];
|
||||
} else if (arg == "--playback" && i + 1 < argc) {
|
||||
opts.playback_file = argv[++i];
|
||||
} else if (arg[0] != '-') {
|
||||
opts.document_path = arg;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user