@@ -133,6 +133,108 @@ test_version_extraction() {
133133 fi
134134}
135135
136+ # List all available tests from feature files
137+ list_tests () {
138+ local feature_pattern=" ${1:- } "
139+ local scenario_pattern=" ${2:- } "
140+
141+ print_status " Listing available features and scenarios..."
142+
143+ # Check if features directory exists
144+ if [ ! -d " features" ]; then
145+ print_error " features directory not found in $( pwd) "
146+ exit 1
147+ fi
148+
149+ local feature_count=0
150+ local scenario_count=0
151+ local current_feature=" "
152+ local current_file=" "
153+
154+ # Find all .feature files
155+ local feature_files
156+ if [ -n " $feature_pattern " ]; then
157+ feature_files=$( find features -name " *.feature" -type f | grep -i " $feature_pattern " | sort)
158+ else
159+ feature_files=$( find features -name " *.feature" -type f | sort)
160+ fi
161+
162+ if [ -z " $feature_files " ]; then
163+ print_warning " No feature files found matching pattern: ${feature_pattern:- ' *' } "
164+ return 0
165+ fi
166+
167+ echo
168+
169+ # Parse each feature file
170+ while IFS= read -r feature_file; do
171+ if [ ! -f " $feature_file " ]; then
172+ continue
173+ fi
174+
175+ current_file=$( basename " $feature_file " )
176+ local feature_name=" "
177+ local feature_description=" "
178+ local show_this_feature=false
179+ local in_feature=false
180+ local next_line_is_description=false
181+
182+ # Read the feature file line by line
183+ while IFS= read -r line || [ -n " $line " ]; do
184+ # Check for Feature: line
185+ if [[ " $line " =~ ^Feature:[[:space:]]* (.+) ]]; then
186+ feature_name=" ${BASH_REMATCH[1]} "
187+ feature_count=$(( feature_count + 1 ))
188+ in_feature=true
189+ next_line_is_description=true
190+
191+ # Check if we should show this feature
192+ if [ -z " $feature_pattern " ] || echo " $feature_name " | grep -qi " $feature_pattern " ; then
193+ show_this_feature=true
194+ echo
195+ echo -e " ${GREEN} Feature:${NC} $feature_name "
196+ echo -e " ${CYAN} File:${NC} $current_file "
197+ fi
198+ # Check for description line (first non-empty line after Feature:)
199+ elif [ " $next_line_is_description " = true ] && [ " $in_feature " = true ]; then
200+ if [[ ! " $line " =~ ^[[:space:]]* $ ]] && [[ ! " $line " =~ ^[[:space:]]* (Background| Scenario| Given| When| Then| And| But) ]]; then
201+ if [ " $show_this_feature " = true ]; then
202+ echo -e " ${CYAN} Description:${NC} $line "
203+ fi
204+ next_line_is_description=false
205+ fi
206+ # Check for Scenario: line
207+ elif [[ " $line " =~ ^[[:space:]]* Scenario:[[:space:]]* (.+) ]] && [ " $in_feature " = true ]; then
208+ local scenario_name=" ${BASH_REMATCH[1]} "
209+ scenario_count=$(( scenario_count + 1 ))
210+ next_line_is_description=false
211+
212+ # Show scenario if feature matches and scenario matches pattern
213+ if [ " $show_this_feature " = true ]; then
214+ if [ -z " $scenario_pattern " ] || echo " $scenario_name " | grep -qi " $scenario_pattern " ; then
215+ echo -e " ${YELLOW} Scenario:${NC} $scenario_name "
216+ fi
217+ fi
218+ elif [ " $next_line_is_description " = true ] && [[ " $line " =~ ^[[:space:]]* $ ]]; then
219+ # Empty line, continue looking for description
220+ continue
221+ else
222+ next_line_is_description=false
223+ fi
224+ done < " $feature_file "
225+ done <<< " $feature_files"
226+
227+ echo
228+ echo
229+ print_success " Found $feature_count feature(s) and $scenario_count scenario(s)"
230+ echo
231+ print_status " To run a specific feature/scenario, use:"
232+ print_status " $0 'FeatureName' # Run all scenarios in a feature"
233+ print_status " $0 'FeatureName/ScenarioName' # Run a specific scenario"
234+ print_status " $0 'FeaturePattern' # Run features matching pattern"
235+ print_status " $0 'FeaturePattern/ScenarioPattern' # Run scenarios matching pattern"
236+ }
237+
136238# Run specific test or all tests
137239run_tests () {
138240 local test_pattern=" ${1:- } "
@@ -226,20 +328,26 @@ show_usage() {
226328 echo
227329 echo " OPTIONS:"
228330 echo " -h, --help Show this help message"
331+ echo " -l, --list [PATTERN] List all available features and scenarios"
332+ echo " Pattern can be 'FeatureName' or 'FeatureName/ScenarioName'"
229333 echo " -p, --parallel N Set parallelism level (default: 1)"
230334 echo " -t, --timeout DURATION Set timeout (default: 60m)"
231335 echo " -c, --cleanup Clean up test resources before running"
232336 echo " -d, --debug Enable debug mode with verbose output"
233337 echo
234338 echo " TEST_PATTERN:"
235- echo " Optional pattern to run specific tests (e.g., 'TestFeatures/conftest ')"
339+ echo " Optional pattern to run specific tests (e.g., 'FeatureName/ScenarioName ')"
236340 echo
237341 echo " Examples:"
238- echo " $0 # Run all tests"
239- echo " $0 -p 2 -t 30m # Run with 2 parallel, 30min timeout"
240- echo " $0 'TestFeatures/conftest' # Run only conftest tests"
241- echo " $0 -c 'TestFeatures/OPA' # Clean up and run OPA tests"
242- echo " $0 -d 'TestFeatures/json_output' # Run with debug output"
342+ echo " $0 -l # List all features and scenarios"
343+ echo " $0 -l 'validate' # List features matching 'validate'"
344+ echo " $0 -l 'validate_image/happy day' # List specific scenario"
345+ echo " $0 # Run all tests"
346+ echo " $0 -p 2 -t 30m # Run with 2 parallel, 30min timeout"
347+ echo " $0 'validate_image' # Run all scenarios in a feature"
348+ echo " $0 'validate_image/happy day' # Run a specific scenario"
349+ echo " $0 -c 'validate_image' # Clean up and run feature"
350+ echo " $0 -d 'validate_image/happy day' # Run with debug output"
243351}
244352
245353# Parse command line arguments
@@ -249,13 +357,36 @@ parse_args() {
249357 local timeout=" 60m"
250358 local test_pattern=" "
251359 local debug=false
360+ local list_only=false
361+ local list_pattern=" "
362+ local list_feature_pattern=" "
363+ local list_scenario_pattern=" "
252364
253365 while [[ $# -gt 0 ]]; do
254366 case $1 in
255367 -h|--help)
256368 show_usage
257369 exit 0
258370 ;;
371+ -l|--list)
372+ list_only=true
373+ # Check if next argument is a pattern (not another option)
374+ if [[ $# -gt 1 ]] && [[ ! " $2 " =~ ^- ]]; then
375+ list_pattern=" $2 "
376+ shift 2
377+ else
378+ shift
379+ fi
380+ # Also check if there's a scenario pattern (Feature/Scenario format)
381+ if [[ -n " $list_pattern " ]] && [[ " $list_pattern " =~ ^([^/]+)/(.+)$ ]]; then
382+ # Pattern contains /, so split it
383+ list_feature_pattern=" ${BASH_REMATCH[1]} "
384+ list_scenario_pattern=" ${BASH_REMATCH[2]} "
385+ else
386+ list_feature_pattern=" $list_pattern "
387+ list_scenario_pattern=" "
388+ fi
389+ ;;
259390 -p|--parallel)
260391 parallel=" $2 "
261392 shift 2
@@ -278,7 +409,12 @@ parse_args() {
278409 exit 1
279410 ;;
280411 * )
281- test_pattern=" $1 "
412+ # If we're listing, treat this as a pattern; otherwise as test pattern
413+ if [ " $list_only " = true ]; then
414+ list_pattern=" $1 "
415+ else
416+ test_pattern=" $1 "
417+ fi
282418 shift
283419 ;;
284420 esac
@@ -290,6 +426,12 @@ parse_args() {
290426 set -x # Enable bash debug mode
291427 fi
292428
429+ # If listing, do that and exit
430+ if [ " $list_only " = true ]; then
431+ list_tests " $list_feature_pattern " " $list_scenario_pattern "
432+ exit 0
433+ fi
434+
293435 # Run cleanup if requested
294436 if [ " $cleanup " = true ]; then
295437 cleanup_test_resources
@@ -301,6 +443,20 @@ parse_args() {
301443
302444# Main execution
303445main () {
446+ # Check if we're just listing tests (quick check without full setup)
447+ for arg in " $@ " ; do
448+ if [[ " $arg " == " -l" ]] || [[ " $arg " == " --list" ]]; then
449+ echo " =========================================="
450+ echo " Listing Acceptance Tests"
451+ echo " =========================================="
452+ echo
453+
454+ # Skip setup for listing - it's not needed
455+ parse_args " $@ "
456+ exit 0
457+ fi
458+ done
459+
304460 echo " =========================================="
305461 echo " Running Acceptance Tests"
306462 echo " =========================================="
0 commit comments