6#include "absl/strings/ascii.h"
7#include "absl/strings/match.h"
8#include "absl/strings/str_cat.h"
9#include "absl/strings/str_format.h"
10#include "absl/strings/str_replace.h"
20 return absl::StrFormat(
"Click(%s)",
target);
22 return absl::StrFormat(
"Type(%s, \"%s\"%s)",
target,
text,
27 return absl::StrFormat(
"Assert(%s)",
condition);
29 return "Screenshot()";
35 std::string result = absl::StrCat(
"Workflow: ",
description,
"\n");
36 for (
size_t i = 0; i <
steps.size(); ++i) {
37 absl::StrAppend(&result,
" ", i + 1,
". ",
steps[i].
ToString(),
"\n");
43 const std::string& prompt) {
44 std::string normalized_prompt = absl::AsciiStrToLower(prompt);
47 std::string editor_name, input_name, text, button_name;
70 return absl::InvalidArgumentError(
72 "Unable to parse prompt: \"%s\"\n\n"
73 "Supported patterns:\n"
74 " - Open <Editor> editor\n"
75 " - Open <Editor> and verify it loads\n"
76 " - Type '<text>' in <input>\n"
77 " - Click <button>\n\n"
79 " - Open Overworld editor\n"
80 " - Open Dungeon editor and verify it loads\n"
81 " - Type 'zelda3.sfc' in filename input\n"
82 " - Click Open ROM button",
87 std::string* editor_name) {
89 std::regex pattern(R
"(open\s+(\w+)(?:\s+editor)?)");
91 if (std::regex_search(prompt, match, pattern) && match.size() > 1) {
92 *editor_name = match[1].str();
99 std::string* editor_name) {
101 std::regex pattern(R
"(open\s+(\w+)(?:\s+editor)?\s+and\s+verify)");
103 if (std::regex_search(prompt, match, pattern) && match.size() > 1) {
104 *editor_name = match[1].str();
111 std::string* input_name,
114 std::regex pattern(R
"(type\s+['"]([^'"]+)['"]\s+in(?:to)?\s+(\w+))");
116 if (std::regex_search(prompt, match, pattern) && match.size() > 2) {
117 *text = match[1].str();
118 *input_name = match[2].str();
125 std::string* button_name) {
127 std::regex pattern(R
"(click\s+([\w\s]+?)(?:\s+button)?\s*$)");
129 if (std::regex_search(prompt, match, pattern) && match.size() > 1) {
130 *button_name = match[1].str();
137 std::string normalized = name;
139 if (!normalized.empty()) {
140 normalized[0] = std::toupper(normalized[0]);
143 if (!absl::StrContains(absl::AsciiStrToLower(normalized),
"editor")) {
144 absl::StrAppend(&normalized,
" Editor");
150 const std::string& editor_name) {
153 TestWorkflow workflow;
154 workflow.description = absl::StrFormat(
"Open %s", normalized_name);
159 click_step.target = absl::StrFormat(
"button:%s",
160 absl::StrReplaceAll(normalized_name,
162 workflow.steps.push_back(click_step);
167 wait_step.condition = absl::StrFormat(
"window_visible:%s", normalized_name);
168 wait_step.timeout_ms = 5000;
169 workflow.steps.push_back(wait_step);
175 const std::string& editor_name) {
178 workflow.description = absl::StrFormat(
"Open and verify %s",
182 TestStep assert_step;
184 assert_step.condition = absl::StrFormat(
"visible:%s",
186 workflow.steps.push_back(assert_step);
192 const std::string& input_name,
const std::string& text) {
193 TestWorkflow workflow;
194 workflow.
description = absl::StrFormat(
"Type '%s' into %s", text, input_name);
199 click_step.target = absl::StrFormat(
"input:%s", input_name);
200 workflow.steps.push_back(click_step);
205 type_step.target = absl::StrFormat(
"input:%s", input_name);
206 type_step.text = text;
207 type_step.clear_first =
true;
208 workflow.steps.push_back(type_step);
214 const std::string& button_name) {
215 TestWorkflow workflow;
216 workflow.
description = absl::StrFormat(
"Click '%s' button", button_name);
220 click_step.target = absl::StrFormat(
"button:%s", button_name);
221 workflow.steps.push_back(click_step);
bool MatchesClickButton(const std::string &prompt, std::string *button_name)
bool MatchesTypeInput(const std::string &prompt, std::string *input_name, std::string *text)
bool MatchesOpenEditor(const std::string &prompt, std::string *editor_name)
TestWorkflow BuildOpenEditorWorkflow(const std::string &editor_name)
TestWorkflow BuildTypeInputWorkflow(const std::string &input_name, const std::string &text)
TestWorkflow BuildClickButtonWorkflow(const std::string &button_name)
bool MatchesOpenAndVerify(const std::string &prompt, std::string *editor_name)
std::string NormalizeEditorName(const std::string &name)
TestWorkflow BuildOpenAndVerifyWorkflow(const std::string &editor_name)
absl::StatusOr< TestWorkflow > GenerateWorkflow(const std::string &prompt)
Generate a test workflow from a natural language prompt.
Main namespace for the application.
std::string ToString() const
std::vector< TestStep > steps
std::string ToString() const