feat: [flow-tester] API 로그 캡처 및 UI 개선

- ApiLogCapturer 추가: 플로우 실행 중 API 로그 캡처
- resolveBaseUrl() 추가: .env 환경변수 기반 baseUrl 지원
- 실행 상세 페이지: 스텝별 접기/펼치기 기능 (성공=접힘, 실패=펼침)
- JSON 가이드 및 예제 플로우 최신화
- AI 프롬프트 템플릿 업데이트
- bindExpectVariables() 추가: expect jsonPath 값에 변수 바인딩 적용
- areNumericEqual() 추가: 숫자 타입 유연 비교 ("2" == 2)
This commit is contained in:
2025-12-04 15:30:04 +09:00
parent 20cfa01579
commit fe10cae06c
9 changed files with 709 additions and 143 deletions

View File

@@ -91,6 +91,12 @@ private function validateValue(mixed $actual, mixed $expected, string $path): ?s
{
// 직접 값 비교 (연산자가 아닌 경우)
if (! is_string($expected) || ! str_starts_with($expected, '@')) {
// 숫자 비교: 둘 다 숫자(또는 숫자 문자열)인 경우 타입 무관하게 비교
// 예: "2" == 2, "123" == 123
if ($this->areNumericEqual($actual, $expected)) {
return null;
}
if ($actual !== $expected) {
return sprintf(
'Path %s: expected %s, got %s',
@@ -266,6 +272,30 @@ private function formatList(array $items): string
return '['.implode(', ', $items).']';
}
/**
* 숫자 값 비교 (타입 무관)
*
* 둘 다 숫자(또는 숫자 문자열)인 경우 값이 같은지 비교합니다.
* 예: "2" == 2 → true, "123" == 123 → true
*/
private function areNumericEqual(mixed $actual, mixed $expected): bool
{
// 둘 다 숫자 또는 숫자 문자열인 경우에만 비교
if (is_numeric($actual) && is_numeric($expected)) {
// 정수 비교가 가능한 경우 정수로 비교
if (is_int($actual) || is_int($expected) ||
(is_string($actual) && ctype_digit(ltrim($actual, '-'))) ||
(is_string($expected) && ctype_digit(ltrim($expected, '-')))) {
return (int) $actual === (int) $expected;
}
// 그 외의 경우 float로 비교
return (float) $actual === (float) $expected;
}
return false;
}
/**
* 응답에서 값 추출 (extract 처리)
*