@@ -76,6 +76,9 @@ class ActionObject
76
76
const ACTION_ATTRIBUTE_USERINPUT = 'userInput ' ;
77
77
const ACTION_TYPE_COMMENT = 'comment ' ;
78
78
const INVISIBLE_STEP_ACTIONS = ['retrieveEntityField ' , 'getSecret ' ];
79
+ const REGEX_SINGLE_GROUP = '[\w]+ ' ;
80
+ const REGEX_WITH_INDEX = '[\w]+\.[\w\[\]]+ ' ;
81
+ const REGEX_WITH_PARAM = '[\w]+\.[\w]+\((?(?!}}).)+\) ' ;
79
82
80
83
/**
81
84
* The unique identifier for the action
@@ -415,6 +418,14 @@ private function resolveUrlReference()
415
418
$ url = $ this ->actionAttributes [ActionObject::ACTION_ATTRIBUTE_URL ];
416
419
417
420
$ replacement = $ this ->findAndReplaceReferences (PageObjectHandler::getInstance (), $ url );
421
+
422
+ $ missingReferences = $ this ->getMissingReferences ($ replacement );
423
+ if (!empty ($ missingReferences )) {
424
+ throw new TestReferenceException (
425
+ sprintf ('Can not resolve replacements: "%s" ' , implode ('", " ' , $ missingReferences ))
426
+ );
427
+ }
428
+
418
429
if ($ replacement ) {
419
430
$ this ->resolvedCustomAttributes [ActionObject::ACTION_ATTRIBUTE_URL ] = $ replacement ;
420
431
$ allPages = PageObjectHandler::getInstance ()->getAllObjects ();
@@ -428,6 +439,27 @@ private function resolveUrlReference()
428
439
}
429
440
}
430
441
442
+ /**
443
+ * Returns array of missing references
444
+ *
445
+ * @param string $replacement
446
+ * @return array
447
+ */
448
+ private function getMissingReferences ($ replacement ): array
449
+ {
450
+ $ matchPatterns = [
451
+ self ::REGEX_SINGLE_GROUP ,
452
+ self ::REGEX_WITH_INDEX ,
453
+ self ::REGEX_WITH_PARAM
454
+ ];
455
+
456
+ preg_match_all ($ this ->getMustachePattern ($ matchPatterns ), $ replacement , $ matches );
457
+
458
+ return array_filter ($ matches [1 ], function ($ match ) {
459
+ return !empty ($ match ) && false === strpos ($ match , '_ENV. ' );
460
+ });
461
+ }
462
+
431
463
/**
432
464
* Look up the value for EntityDataObjectName.Key and set it as the corresponding attribute in the resolved custom
433
465
* attributes.
@@ -521,10 +553,12 @@ private function stripAndReturnParameters($reference)
521
553
*/
522
554
private function findAndReplaceReferences ($ objectHandler , $ inputString )
523
555
{
524
- //look for parameter area, if so use different regex
525
- $ regex = ActionObject::ACTION_ATTRIBUTE_VARIABLE_REGEX_PATTERN ;
556
+ $ matchPatterns = [
557
+ self ::REGEX_WITH_INDEX ,
558
+ self ::REGEX_WITH_PARAM
559
+ ];
526
560
527
- preg_match_all ($ regex , $ inputString , $ matches );
561
+ preg_match_all ($ this -> getMustachePattern ( $ matchPatterns ) , $ inputString , $ matches );
528
562
529
563
$ outputString = $ inputString ;
530
564
@@ -722,7 +756,11 @@ private function resolveParameterization($isParameterized, $replacement, $match,
722
756
*/
723
757
private function matchParameterReferences ($ reference , $ parameters )
724
758
{
725
- preg_match_all ('/{{[\w.]+}}/ ' , $ reference , $ varMatches );
759
+ $ matchPatterns = [
760
+ self ::REGEX_SINGLE_GROUP
761
+ ];
762
+
763
+ preg_match_all ($ this ->getMustachePattern ($ matchPatterns ), $ reference , $ varMatches );
726
764
$ varMatches [0 ] = array_unique ($ varMatches [0 ]);
727
765
$ this ->checkParameterCount ($ varMatches [0 ], $ parameters , $ reference );
728
766
@@ -793,6 +831,17 @@ private function checkParameterCount($matches, $parameters, $reference)
793
831
}
794
832
}
795
833
834
+ /**
835
+ * Returns Mustache regex pattern
836
+ *
837
+ * @param array|null $patterns
838
+ * @return string
839
+ */
840
+ private function getMustachePattern (array $ patterns = []): string
841
+ {
842
+ return '/({{ ' .implode ('}})|({{ ' , $ patterns ).'}})/ ' ;
843
+ }
844
+
796
845
/**
797
846
* Returns array of deprecated usages in Action.
798
847
*
0 commit comments