3#include "absl/flags/declare.h"
4#include "absl/flags/flag.h"
5#include "absl/strings/numbers.h"
6#include "absl/strings/str_format.h"
7#include "absl/strings/str_join.h"
24 auto tile_id_str = parser.
GetString(
"tile").value();
25 auto x_str = parser.
GetString(
"x").value();
26 auto y_str = parser.
GetString(
"y").value();
29 if (!ParseHexString(tile_id_str, &tile_id) ||
30 !absl::SimpleAtoi(x_str, &x) ||
31 !absl::SimpleAtoi(y_str, &y)) {
32 return absl::InvalidArgumentError(
"Invalid tile ID or coordinate format.");
38 return absl::UnavailableError(
"Failed to connect to GUI server: " +
39 std::string(status.message()));
43 std::string canvas_id =
"overworld";
44 status = client.
SetTile(canvas_id, x, y, tile_id);
47 formatter.
AddField(
"tile_id", absl::StrFormat(
"0x%03X", tile_id));
51 formatter.
AddField(
"status",
"Success");
53 formatter.
AddField(
"status",
"Failed");
54 formatter.
AddField(
"error", std::string(status.message()));
64 auto target = parser.
GetString(
"target").value();
65 auto click_type_str = parser.
GetString(
"click-type").value_or(
"left");
68 if (click_type_str ==
"right")
70 else if (click_type_str ==
"double")
76 return absl::UnavailableError(
"Failed to connect to GUI server: " +
77 std::string(status.message()));
80 auto result = client.
Click(target, click_type);
83 formatter.
AddField(
"target", target);
84 formatter.
AddField(
"click_type", click_type_str);
87 formatter.
AddField(
"status", result->success ?
"Success" :
"Failed");
88 if (!result->success) {
89 formatter.
AddField(
"error", result->message);
91 formatter.
AddField(
"execution_time_ms",
92 static_cast<int>(result->execution_time.count()));
94 formatter.
AddField(
"status",
"Error");
95 formatter.
AddField(
"error", std::string(result.status().message()));
99 return result.status();
105 auto window = parser.
GetString(
"window").value_or(
"");
106 auto type_str = parser.
GetString(
"type").value_or(
"all");
109 bool is_summary = (
GetName() ==
"gui-summarize-widgets");
112 auto status = client.
Connect();
114 return absl::UnavailableError(
"Failed to connect to GUI server: " +
115 std::string(status.message()));
125 formatter.
BeginObject(is_summary ?
"GUI Summary" :
"Widget Discovery");
126 formatter.
AddField(
"window_filter", window);
129 formatter.
AddField(
"total_widgets", result->total_widgets);
130 formatter.
AddField(
"status",
"Success");
133 for (
const auto& win : result->windows) {
134 if (!win.visible && is_summary)
138 formatter.
AddField(
"name", win.name);
139 formatter.
AddField(
"visible", win.visible);
142 std::vector<std::string> highlights;
143 for (
const auto& w : win.widgets) {
144 if (w.type ==
"button" || w.type ==
"input" || w.type ==
"menu") {
145 highlights.push_back(absl::StrFormat(
"%s (%s)", w.label, w.type));
147 if (highlights.size() > 10)
150 formatter.
AddField(
"key_elements", absl::StrJoin(highlights,
", "));
154 for (
const auto& widget : win.widgets) {
157 formatter.
AddArrayItem(absl::StrFormat(
"%s (%s) - %s", widget.label,
158 widget.type, widget.path));
166 formatter.
AddField(
"status",
"Error");
167 formatter.
AddField(
"error", std::string(result.status().message()));
171 return result.status();
177 auto region = parser.
GetString(
"region").value_or(
"full");
178 auto image_format = parser.
GetString(
"format").value_or(
"PNG");
181 auto status = client.
Connect();
183 return absl::UnavailableError(
"Failed to connect to GUI server: " +
184 std::string(status.message()));
187 auto result = client.
Screenshot(region, image_format);
190 formatter.
AddField(
"region", region);
191 formatter.
AddField(
"image_format", image_format);
194 formatter.
AddField(
"status", result->success ?
"Success" :
"Failed");
195 if (result->success) {
196 formatter.
AddField(
"output_path", result->message);
199 if (!absl::GetFlag(FLAGS_quiet)) {
200 std::cerr <<
"\n📸 \033[1;32mScreenshot captured!\033[0m\n";
201 std::cerr <<
" Path: \033[1;34m" << result->message <<
"\033[0m\n\n";
204 formatter.
AddField(
"error", result->message);
207 formatter.
AddField(
"status",
"Error");
208 formatter.
AddField(
"error", std::string(result.status().message()));
212 return result.status();
The Rom class is used to load, save, and modify Rom data. This is a generic SNES ROM container and do...
absl::Status SetTile(const std::string &canvas_id, int x, int y, int tile_id)
Client for automating YAZE GUI through gRPC.
absl::StatusOr< AutomationResult > Screenshot(const std::string ®ion="full", const std::string &format="PNG")
Capture a screenshot.
absl::Status Connect()
Connect to the test harness server.
absl::StatusOr< DiscoverWidgetsResult > DiscoverWidgets(const DiscoverWidgetsQuery &query)
absl::StatusOr< AutomationResult > Click(const std::string &target, ClickType type=ClickType::kLeft)
Click a GUI element.
absl::Status Execute(Rom *rom, const resources::ArgumentParser &parser, resources::OutputFormatter &formatter) override
Execute the command business logic.
absl::Status Execute(Rom *rom, const resources::ArgumentParser &parser, resources::OutputFormatter &formatter) override
Execute the command business logic.
absl::Status Execute(Rom *rom, const resources::ArgumentParser &parser, resources::OutputFormatter &formatter) override
Execute the command business logic.
Utility for parsing common CLI argument patterns.
std::optional< std::string > GetString(const std::string &name) const
Parse a named argument (e.g., –format=json or –format json)
ABSL_DECLARE_FLAG(std::string, gui_server_address)
bool ParseHexString(absl::string_view str, int *out)
ClickType
Type of click action to perform.