5#include "absl/strings/ascii.h"
6#include "absl/strings/str_cat.h"
7#include "absl/strings/str_format.h"
8#include "absl/time/clock.h"
9#include "absl/time/time.h"
21#if defined(YAZE_WITH_GRPC)
22const char* HarnessStatusToString(test::HarnessTestStatus status) {
24 case HarnessTestStatus::kQueued:
26 case HarnessTestStatus::kRunning:
28 case HarnessTestStatus::kPassed:
30 case HarnessTestStatus::kFailed:
32 case HarnessTestStatus::kTimeout:
34 case HarnessTestStatus::kUnspecified:
45 : recorder_(recorder), active_(active) {}
48 if (!recorder_ || !active_) {
51 absl::MutexLock lock(&recorder_->mu_);
52 recorder_->suspended_ =
false;
60 absl::MutexLock lock(&
mu_);
65 const std::string& recording_id,
bool discard) {
66 absl::MutexLock lock(&
mu_);
71 absl::MutexLock lock(&
mu_);
76 absl::MutexLock lock(&
mu_);
77 return recording_ && !suspended_;
81 absl::MutexLock lock(&
mu_);
86 absl::MutexLock lock(&
mu_);
87 bool activate =
false;
98 return absl::FailedPreconditionError(
99 "A recording session is already active");
102 return absl::FailedPreconditionError(
"TestManager unavailable");
105 return absl::InvalidArgumentError(
106 "Recording requires a non-empty output path");
112 if (options_.session_name.empty()) {
115 started_at_ = absl::Now();
118 return recording_id_;
122 const std::string& recording_id,
bool discard) {
124 return absl::FailedPreconditionError(
"No active recording session");
126 if (!recording_id.empty() && recording_id != recording_id_) {
127 return absl::InvalidArgumentError(
128 absl::StrFormat(
"Recording ID mismatch (expected %s)", recording_id_));
132 summary.
step_count =
static_cast<int>(steps_.size());
133 summary.
duration = absl::Now() - started_at_;
135 summary.
saved = !discard;
141 script.
name = options_.session_name;
146 for (
const auto& step : steps_) {
149 script_step.
target = step.target;
150 script_step.
click_type = absl::AsciiStrToLower(step.click_type);
151 script_step.
text = step.text;
155 script_step.
region = step.region;
156 script_step.
format = step.format;
158#if defined(YAZE_WITH_GRPC)
160 ::yaze::test::HarnessStatusToString(step.final_status);
164 if (!step.final_error_message.empty()) {
171 script.
steps.push_back(std::move(script_step));
181 recording_id_.clear();
183 started_at_ = absl::InfinitePast();
190 if (!recording_ || suspended_) {
197 steps_.push_back(std::move(copy));
202 return absl::FailedPreconditionError(
"TestManager unavailable");
205#if !defined(YAZE_WITH_GRPC)
206 return absl::OkStatus();
208 for (
auto& step : steps_) {
209 if (step.test_id.empty()) {
213 const absl::Time deadline = absl::Now() + kTestCompletionTimeout;
214 while (absl::Now() < deadline) {
215 absl::StatusOr<test::HarnessTestExecution> execution =
217 if (!execution.ok()) {
218 absl::SleepFor(kPollInterval);
222 step.final_status = execution->status;
223 step.final_error_message = execution->error_message;
224 step.assertion_failures = execution->assertion_failures;
225 step.metrics = execution->metrics;
227 if (execution->status == test::HarnessTestStatus::kQueued ||
228 execution->status == test::HarnessTestStatus::kRunning) {
229 absl::SleepFor(kPollInterval);
236 return absl::OkStatus();
241 return absl::StrFormat(
243 absl::FormatTime(
"%Y%m%dT%H%M%S", absl::Now(), absl::UTCTimeZone()));
ScopedSuspension(TestRecorder *recorder, bool active)
void RecordStepLocked(const RecordedStep &step) ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu_)
static std::string GenerateRecordingId()
absl::StatusOr< StopRecordingSummary > StopLocked(const std::string &recording_id, bool discard) ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu_)
absl::Status PopulateFinalStatusLocked() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu_)
TestManager *const test_manager_
TestRecorder(TestManager *test_manager)
absl::StatusOr< std::string > Start(const RecordingOptions &options)
absl::StatusOr< StopRecordingSummary > Stop(const std::string &recording_id, bool discard)
ScopedSuspension Suspend()
static const char * ActionTypeToString(ActionType type)
absl::StatusOr< std::string > StartLocked(const RecordingOptions &options) ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu_)
void RecordStep(const RecordedStep &step)
std::string CurrentRecordingId() const
static absl::Status WriteToFile(const TestScript &script, const std::string &path)
constexpr absl::Duration kPollInterval
constexpr absl::Duration kTestCompletionTimeout
#define RETURN_IF_ERROR(expr)
std::vector< std::string > expect_assertion_failures
std::string expect_status
std::string expect_message
std::map< std::string, int32_t > expect_metrics
std::vector< TestScriptStep > steps