@@ -216,6 +216,7 @@ class TestItem:
216
216
range : Optional [Range ] = None
217
217
tags : Optional [List [str ]] = None
218
218
error : Optional [str ] = None
219
+ rpa : Optional [bool ] = None
219
220
220
221
221
222
@dataclass
@@ -228,7 +229,9 @@ class ResultItem:
228
229
class Statistics :
229
230
suites : int = 0
230
231
suites_with_tests : int = 0
232
+ suites_with_tasks : int = 0
231
233
tests : int = 0
234
+ tasks : int = 0
232
235
233
236
234
237
def get_rel_source (source : Optional [str ]) -> Optional [str ]:
@@ -254,7 +257,7 @@ def __init__(self) -> None:
254
257
)
255
258
self ._current = self .all
256
259
self .suites : List [TestItem ] = []
257
- self .tests : List [TestItem ] = []
260
+ self .test_and_tasks : List [TestItem ] = []
258
261
self .tags : Dict [str , List [TestItem ]] = defaultdict (list )
259
262
self .normalized_tags : Dict [str , List [TestItem ]] = defaultdict (list )
260
263
self .statistics = Statistics ()
@@ -294,6 +297,7 @@ def visit_suite(self, suite: TestSuite) -> None:
294
297
),
295
298
children = [],
296
299
error = suite .error_message if isinstance (suite , ErroneousTestSuite ) else None ,
300
+ rpa = suite .rpa ,
297
301
)
298
302
except ValueError as e :
299
303
raise ValueError (f"Error while parsing suite { suite .source } : { e } " ) from e
@@ -313,7 +317,10 @@ def visit_suite(self, suite: TestSuite) -> None:
313
317
314
318
self .statistics .suites += 1
315
319
if suite .tests :
316
- self .statistics .suites_with_tests += 1
320
+ if suite .rpa :
321
+ self .statistics .suites_with_tasks += 1
322
+ else :
323
+ self .statistics .suites_with_tests += 1
317
324
318
325
def end_suite (self , _suite : TestSuite ) -> None :
319
326
self ._collected .pop ()
@@ -332,7 +339,7 @@ def visit_test(self, test: TestCase) -> None:
332
339
try :
333
340
absolute_path = normalized_path (Path (test .source )) if test .source is not None else None
334
341
item = TestItem (
335
- type = "test" ,
342
+ type = "task" if self . _current . rpa else " test" ,
336
343
id = f"{ absolute_path or '' } ;{ test .longname } ;{ test .lineno } " ,
337
344
name = test .name ,
338
345
longname = test .longname ,
@@ -344,6 +351,7 @@ def visit_test(self, test: TestCase) -> None:
344
351
end = Position (line = test .lineno - 1 , character = 0 ),
345
352
),
346
353
tags = list (set (normalize (str (t ), ignore = "_" ) for t in test .tags )) if test .tags else None ,
354
+ rpa = self ._current .rpa ,
347
355
)
348
356
except ValueError as e :
349
357
raise ValueError (f"Error while parsing suite { test .source } : { e } " ) from e
@@ -352,10 +360,12 @@ def visit_test(self, test: TestCase) -> None:
352
360
self .tags [str (tag )].append (item )
353
361
self .normalized_tags [normalize (str (tag ), ignore = "_" )].append (item )
354
362
355
- self .tests .append (item )
363
+ self .test_and_tasks .append (item )
356
364
self ._current .children .append (item )
357
-
358
- self .statistics .tests += 1
365
+ if self ._current .rpa :
366
+ self .statistics .tasks += 1
367
+ else :
368
+ self .statistics .tests += 1
359
369
360
370
361
371
@click .group (invoke_without_command = False )
@@ -543,6 +553,28 @@ def handle_options(
543
553
raise UnknownError ("Unexpected error happened." )
544
554
545
555
556
+ def print_statistics (app : Application , suite : TestSuite , collector : Collector ) -> None :
557
+ def print () -> Iterable [str ]:
558
+ yield click .style ("Statistics:" , underline = True , fg = "blue" )
559
+ yield os .linesep
560
+ yield click .style (" - Suites: " , underline = True , bold = True , fg = "blue" )
561
+ yield f"{ collector .statistics .suites } { os .linesep } "
562
+ if collector .statistics .suites_with_tests :
563
+ yield click .style (" - Suites with tests: " , underline = True , bold = True , fg = "blue" )
564
+ yield f"{ collector .statistics .suites_with_tests } { os .linesep } "
565
+ if collector .statistics .suites_with_tasks :
566
+ yield click .style (" - Suites with tasks: " , underline = True , bold = True , fg = "blue" )
567
+ yield f"{ collector .statistics .suites_with_tasks } { os .linesep } "
568
+ if collector .statistics .tests :
569
+ yield click .style (" - Tests: " , underline = True , bold = True , fg = "blue" )
570
+ yield f"{ collector .statistics .tests } { os .linesep } "
571
+ if collector .statistics .tasks :
572
+ yield click .style (" - Tasks: " , underline = True , bold = True , fg = "blue" )
573
+ yield f"{ collector .statistics .tasks } { os .linesep } "
574
+
575
+ app .echo_via_pager (print ())
576
+
577
+
546
578
@discover .command (
547
579
context_settings = {"allow_extra_args" : True , "ignore_unknown_options" : True },
548
580
add_help_option = True ,
@@ -551,7 +583,7 @@ def handle_options(
551
583
@click .option (
552
584
"--tags / --no-tags" ,
553
585
"show_tags" ,
554
- default = False ,
586
+ default = True ,
555
587
show_default = True ,
556
588
help = "Show the tags that are present." ,
557
589
)
@@ -591,48 +623,70 @@ def all(
591
623
592
624
if collector .all .children :
593
625
if app .config .output_format is None or app .config .output_format == OutputFormat .TEXT :
594
- tests_or_tasks = "Task" if suite .rpa else "Test"
595
626
596
627
def print (item : TestItem , indent : int = 0 ) -> Iterable [str ]:
597
- type = click .style (
598
- item .type .capitalize () if item .type == "suite" else tests_or_tasks .capitalize (),
599
- fg = "green" ,
600
- )
601
-
602
- if item .type == "test" :
628
+ if item .type in ["test" , "task" ]:
603
629
yield " "
604
- yield type
605
- yield click .style (f": { item .longname } " , bold = True )
630
+ yield click . style ( f" { item . type . capitalize () } : " , fg = "blue" )
631
+ yield click .style (item .longname , bold = True )
606
632
yield click .style (
607
633
f" ({ item .source if full_paths else item .rel_source } "
608
634
f":{ item .range .start .line + 1 if item .range is not None else 1 } ){ os .linesep } "
609
635
)
610
636
if show_tags and item .tags :
611
- yield click .style (" Tags:" , bold = True , fg = "green " )
637
+ yield click .style (" Tags:" , bold = True , fg = "yellow " )
612
638
yield f" { ', ' . join (normalize (str (tag ), ignore = '_' ) for tag in sorted (item .tags ))} { os .linesep } "
613
639
else :
614
- yield type
615
- yield f": { item .longname } "
640
+ yield click . style ( f" { item . type . capitalize () } : " , fg = "green" )
641
+ yield click . style ( item .longname , bold = True )
616
642
yield click .style (f" ({ item .source if full_paths else item .rel_source } ){ os .linesep } " )
617
643
for child in item .children or []:
618
644
yield from print (child , indent + 2 )
619
645
620
- if indent == 0 :
621
- yield os .linesep
622
-
623
- yield click .style ("Suites: " , underline = True , bold = True , fg = "blue" )
624
- yield f"{ collector .statistics .suites } { os .linesep } "
625
- yield click .style (f"Suites with { tests_or_tasks } : " , underline = True , bold = True , fg = "blue" )
626
- yield f"{ collector .statistics .suites_with_tests } { os .linesep } "
627
- yield click .style (f"{ tests_or_tasks } : " , underline = True , bold = True , fg = "blue" )
628
- yield f"{ collector .statistics .tests } { os .linesep } "
629
-
630
646
app .echo_via_pager (print (collector .all .children [0 ]))
647
+ print_statistics (app , suite , collector )
631
648
632
649
else :
633
650
app .print_data (ResultItem ([collector .all ], diagnostics ), remove_defaults = True )
634
651
635
652
653
+ def _test_or_tasks (
654
+ selected_type : str ,
655
+ app : Application ,
656
+ full_paths : bool ,
657
+ show_tags : bool ,
658
+ by_longname : Tuple [str , ...],
659
+ exclude_by_longname : Tuple [str , ...],
660
+ robot_options_and_args : Tuple [str , ...],
661
+ ) -> None :
662
+ suite , collector , diagnostics = handle_options (app , by_longname , exclude_by_longname , robot_options_and_args )
663
+
664
+ if collector .all .children :
665
+ if app .config .output_format is None or app .config .output_format == OutputFormat .TEXT :
666
+
667
+ def print (items : List [TestItem ]) -> Iterable [str ]:
668
+ for item in items :
669
+ if item .type != selected_type :
670
+ continue
671
+
672
+ yield click .style (f"{ item .type .capitalize ()} : " , fg = "blue" )
673
+ yield click .style (item .longname , bold = True )
674
+ yield click .style (
675
+ f" ({ item .source if full_paths else item .rel_source } "
676
+ f":{ item .range .start .line + 1 if item .range is not None else 1 } ){ os .linesep } "
677
+ )
678
+ if show_tags and item .tags :
679
+ yield click .style (" Tags:" , bold = True , fg = "yellow" )
680
+ yield f" { ', ' . join (normalize (str (tag ), ignore = '_' ) for tag in sorted (item .tags ))} { os .linesep } "
681
+
682
+ if collector .test_and_tasks :
683
+ app .echo_via_pager (print (collector .test_and_tasks ))
684
+ print_statistics (app , suite , collector )
685
+
686
+ else :
687
+ app .print_data (ResultItem (collector .test_and_tasks , diagnostics ), remove_defaults = True )
688
+
689
+
636
690
@discover .command (
637
691
context_settings = {"allow_extra_args" : True , "ignore_unknown_options" : True },
638
692
add_help_option = True ,
@@ -677,34 +731,53 @@ def tests(
677
731
```
678
732
"""
679
733
680
- suite , collector , diagnostics = handle_options (app , by_longname , exclude_by_longname , robot_options_and_args )
681
-
682
- if collector .all .children :
683
- if app .config .output_format is None or app .config .output_format == OutputFormat .TEXT :
734
+ _test_or_tasks ("test" , app , full_paths , show_tags , by_longname , exclude_by_longname , robot_options_and_args )
684
735
685
- tests_or_tasks = "Task" if suite .rpa else "Test"
686
736
687
- def print (items : List [TestItem ]) -> Iterable [str ]:
688
- for item in items :
689
- type = click .style (
690
- item .type .capitalize () if item .type == "suite" else tests_or_tasks .capitalize (),
691
- fg = "blue" ,
692
- )
693
- yield type
694
- yield click .style (f": { item .longname } " , bold = True )
695
- yield click .style (
696
- f" ({ item .source if full_paths else item .rel_source } "
697
- f":{ item .range .start .line + 1 if item .range is not None else 1 } ){ os .linesep } "
698
- )
699
- if show_tags and item .tags :
700
- yield click .style (" Tags:" , bold = True , fg = "green" )
701
- yield f" { ', ' . join (normalize (str (tag ), ignore = '_' ) for tag in sorted (item .tags ))} { os .linesep } "
737
+ @discover .command (
738
+ context_settings = {"allow_extra_args" : True , "ignore_unknown_options" : True },
739
+ add_help_option = True ,
740
+ epilog = "Use `-- --help` to see `robot` help." ,
741
+ )
742
+ @click .option (
743
+ "--tags / --no-tags" ,
744
+ "show_tags" ,
745
+ default = False ,
746
+ show_default = True ,
747
+ help = "Show the tags that are present." ,
748
+ )
749
+ @click .option (
750
+ "--full-paths / --no-full-paths" ,
751
+ "full_paths" ,
752
+ default = False ,
753
+ show_default = True ,
754
+ help = "Show full paths instead of releative." ,
755
+ )
756
+ @add_options (* ROBOT_OPTIONS )
757
+ @pass_application
758
+ def tasks (
759
+ app : Application ,
760
+ full_paths : bool ,
761
+ show_tags : bool ,
762
+ by_longname : Tuple [str , ...],
763
+ exclude_by_longname : Tuple [str , ...],
764
+ robot_options_and_args : Tuple [str , ...],
765
+ ) -> None :
766
+ """\
767
+ Discover tasks with the selected configuration, profiles, options and
768
+ arguments.
702
769
703
- if collector .tests :
704
- app .echo_via_pager (print (collector .tests ))
770
+ You can use all known `robot` arguments to filter for example by tags or to use pre-run-modifier.
705
771
706
- else :
707
- app .print_data (ResultItem (collector .tests , diagnostics ), remove_defaults = True )
772
+ \b
773
+ Examples:
774
+ ```
775
+ robotcode discover tasks
776
+ robotcode --profile regression discover tasks
777
+ robotcode --profile regression discover tasks --include regression --exclude wipANDnotready
778
+ ```
779
+ """
780
+ _test_or_tasks ("task" , app , full_paths , show_tags , by_longname , exclude_by_longname , robot_options_and_args )
708
781
709
782
710
783
@discover .command (
@@ -743,7 +816,7 @@ def suites(
743
816
```
744
817
"""
745
818
746
- _suite , collector , diagnostics = handle_options (app , by_longname , exclude_by_longname , robot_options_and_args )
819
+ suite , collector , diagnostics = handle_options (app , by_longname , exclude_by_longname , robot_options_and_args )
747
820
748
821
if collector .all .children :
749
822
if app .config .output_format is None or app .config .output_format == OutputFormat .TEXT :
@@ -760,6 +833,8 @@ def print(items: List[TestItem]) -> Iterable[str]:
760
833
if collector .suites :
761
834
app .echo_via_pager (print (collector .suites ))
762
835
836
+ print_statistics (app , suite , collector )
837
+
763
838
else :
764
839
app .print_data (ResultItem (collector .suites , diagnostics ), remove_defaults = True )
765
840
@@ -788,6 +863,13 @@ class TagsResult:
788
863
show_default = True ,
789
864
help = "Show tests where the tag is present." ,
790
865
)
866
+ @click .option (
867
+ "--tasks / --no-tasks" ,
868
+ "show_tasks" ,
869
+ default = False ,
870
+ show_default = True ,
871
+ help = "Show tasks where the tag is present." ,
872
+ )
791
873
@click .option (
792
874
"--full-paths / --no-full-paths" ,
793
875
"full_paths" ,
@@ -801,6 +883,7 @@ def tags(
801
883
app : Application ,
802
884
normalized : bool ,
803
885
show_tests : bool ,
886
+ show_tasks : bool ,
804
887
full_paths : bool ,
805
888
by_longname : Tuple [str , ...],
806
889
exclude_by_longname : Tuple [str , ...],
@@ -822,7 +905,7 @@ def tags(
822
905
```
823
906
"""
824
907
825
- _suite , collector , _diagnostics = handle_options (app , by_longname , exclude_by_longname , robot_options_and_args )
908
+ suite , collector , _diagnostics = handle_options (app , by_longname , exclude_by_longname , robot_options_and_args )
826
909
827
910
if collector .all .children :
828
911
if app .config .output_format is None or app .config .output_format == OutputFormat .TEXT :
@@ -832,18 +915,26 @@ def print(tags: Dict[str, List[TestItem]]) -> Iterable[str]:
832
915
yield click .style (
833
916
f"{ tag } { os .linesep } " ,
834
917
bold = show_tests ,
835
- fg = "green " if show_tests else None ,
918
+ fg = "yellow " if show_tests else None ,
836
919
)
837
- if show_tests :
920
+ if show_tests or show_tasks :
838
921
for t in items :
839
- yield click .style (f" { t .longname } " , bold = True ) + click .style (
922
+ if show_tests != show_tasks :
923
+ if show_tests and t .type != "test" :
924
+ continue
925
+ if show_tasks and t .type != "task" :
926
+ continue
927
+ yield click .style (f" { t .type .capitalize ()} : " , fg = "blue" )
928
+ yield click .style (t .longname , bold = True ) + click .style (
840
929
f" ({ t .source if full_paths else t .rel_source } "
841
930
f":{ t .range .start .line + 1 if t .range is not None else 1 } ){ os .linesep } "
842
931
)
843
932
844
933
if collector .normalized_tags :
845
934
app .echo_via_pager (print (collector .normalized_tags if normalized else collector .tags ))
846
935
936
+ print_statistics (app , suite , collector )
937
+
847
938
else :
848
939
app .print_data (TagsResult (collector .normalized_tags ), remove_defaults = True )
849
940
0 commit comments