#FEATURE by exept
authorClaus Gittinger <cg@exept.de>
Thu, 24 Oct 2019 00:31:06 +0200
changeset 3799 bbb4c1dbce25
parent 3798 eafc4c1bb53e
child 3800 fb1763b613bf
#FEATURE by exept class: ShowMeHowItWorks class definition added: #pinPOForPin:ofStep: #timeout: comment/format in: #clear #click #click: #clickIn: #fastMoveTo: #key: #moveTo: #press: #release: #wait: changed: #componentNamed: #findComponent:in: #freezePin:ofStep:with: #isEmpty: #movePointerToComponent:speed: #selectPin:ofStep: #waitFor:timeout: class: ShowMeHowItWorks class comment/format in: #scriptFormat class: ShowMeHowItWorks::ItemInView added: #itemValue
ShowMeHowItWorks.st
--- a/ShowMeHowItWorks.st	Sun Oct 20 16:38:40 2019 +0200
+++ b/ShowMeHowItWorks.st	Thu Oct 24 00:31:06 2019 +0200
@@ -8,7 +8,7 @@
 	instanceVariableNames:'application opStream streamStack lastComponentName lastComponent
 		lastResult voice translate language verifying
 		closeApplicationWhenFinished defaultComponentWaitTime ui
-		theShowFile'
+		theShowFile defaultElementTimeout'
 	classVariableNames:'IntroShownCount DebugMode StartLabel'
 	poolDictionaries:''
 	category:'Interface-Help'
@@ -91,6 +91,10 @@
 
         open            'nameOfAppModelClass'
                                             open an application (class)
+
+        raise           'application'
+        raise           'masterApplication'
+
         intro           
 
 component naming:
@@ -238,12 +242,8 @@
     (diagramEditor := lastComponent) isScrollWrapper ifTrue:[
         diagramEditor := lastComponent scrolledView
     ].
-    pinPO := diagramEditor 
-            detectPOForWhich:[:po |
-                po isPin 
-                and:[ po name = pinName
-                and:[ po owningStepPO name = stepName ]]
-            ].
+    pinPO := self pinPOForPin:pinName ofStep:stepName. 
+
     diagramEditor selection:{ pinPO }.
     diagramEditor doubleClickOn:pinPO.
     self fastMoveTo:(lastComponentName,'/','EditField').
@@ -337,20 +337,14 @@
 selectPin:pinName ofStep:stepName
     <action>
 
-    |diagramEditor pinPo|
+    |diagramEditor pinPO|
 
     (diagramEditor := lastComponent) isScrollWrapper ifTrue:[
         diagramEditor := lastComponent scrolledView
     ].
-    pinPo := diagramEditor 
-            detectPOForWhich:[:po |
-                po isPin 
-                and:[ po name = pinName
-                and:[ po owningStepPO name = stepName ]]
-            ].
-    self movePointerToComponent:diagramEditor offset:pinPo frame center.
-    diagramEditor selection:{ pinPo }. 
-
+    pinPO := self pinPOForPin:pinName ofStep:stepName. 
+    self movePointerToComponent:diagramEditor offset:pinPO frame center.
+    diagramEditor selection:{ pinPO }. 
 !
 
 show:message
@@ -464,6 +458,14 @@
     "Created: / 23-07-2019 / 10:50:43 / Claus Gittinger"
 !
 
+timeout:seconds
+    <action>
+
+    defaultElementTimeout := seconds.
+
+    "Created: / 23-07-2019 / 10:27:02 / Claus Gittinger"
+!
+
 wait:seconds
     <action>
     
@@ -479,16 +481,18 @@
 waitFor:componentName timeout:seconds
     <action>
 
-    |endTime|
+    |endTime component|
 
     verifying ifTrue:[^ self].
 
+    lastComponentName := componentName.
     endTime := Timestamp now + seconds.
     [   
-        (self findComponent:componentName inAllApplications:true ifMultiple:nil) notNil ifTrue:[
+        (component := self findComponent:componentName inAllApplications:true ifMultiple:nil) notNil ifTrue:[
+            lastComponent := component.
             ^ self
         ].
-        Delay waitForSeconds:0.05.
+        Delay waitForSeconds:0.1.
         Timestamp now > endTime ifTrue:[
             self error:('component %1 not present after %2' bindWith:componentName with:seconds)
         ]
@@ -498,6 +502,9 @@
 !ShowMeHowItWorks methodsFor:'commands - checking'!
 
 isEmpty:componentName
+    "true if the addressed textview/field is empty.
+     Leaves component in lastComponent"
+
     <action>
 
     |component|
@@ -506,10 +513,8 @@
     component isScrollWrapper ifTrue:[ component := component scrolledView ].
     component isTextView ifTrue:[
         ^ component contents isEmptyOrNil
-    ] ifFalse:[
-        self halt.
     ].
-    self error:'isEmpty: unhandled component type: ',component displayString.
+    self error:'isEmpty: unhandled (non-text) component type: ',component displayString.
 
     "Created: / 19-07-2019 / 15:33:47 / Claus Gittinger"
 !
@@ -530,7 +535,7 @@
 !ShowMeHowItWorks methodsFor:'commands - mouse & keyboard'!
 
 clear
-    "clear entry fields"
+    "clear entry fields of last component"
 
     <action>
 
@@ -540,7 +545,7 @@
 !
 
 click
-    "press-release"
+    "press-release in last component"
     
     <action>
 
@@ -550,7 +555,7 @@
 !
 
 click:buttonNr
-    "press-release"
+    "press-release in last component"
     
     <action>
 
@@ -562,7 +567,8 @@
 !
 
 clickIn:componentName
-    "press-release"
+    "press-release.
+     Leaves component in lastComponent"
     
     <action>
 
@@ -718,7 +724,8 @@
 !
 
 fastMoveTo:componentName
-    "move the mouse to componentName without circling"
+    "move the mouse to componentName without circling.
+     Leaves component in lastComponent"
 
     <action>
 
@@ -738,7 +745,7 @@
 !
 
 key:aKeySymbol
-    "press/release a key"
+    "press/release a key in last component"
 
     <action>
 
@@ -755,7 +762,8 @@
 
 moveTo:componentName
     "move the mouse to componentName,
-     then circle around it a few times"
+     then circle around it a few times.
+     Leaves component in lastComponent"
 
     <action>
 
@@ -773,7 +781,7 @@
 press:buttonNr
     <action>
 
-    "press at the current position"
+    "press at the current position in last component"
 
     self assert:(buttonNr isInteger).
     ^ self press:buttonNr inComponent:lastComponent.
@@ -811,7 +819,7 @@
 release:buttonNr
     <action>
 
-    "release at the current position"
+    "release at the current position in last component"
     
     <action>
 
@@ -1208,6 +1216,11 @@
 
     |component|
 
+    verifying ifFalse:[
+        self waitFor:componentName timeout:(defaultElementTimeout ? 1).
+        ^ lastComponent.
+    ].
+
     lastComponentName := componentName.
 
     component := self findComponent:componentName.
@@ -1310,10 +1323,10 @@
             idxString includesMatchCharacters ifTrue:[
                 item := 
                     anApplicationOrViewOrMenuItem itemForWhich:[:item |
-                        (item nameKey matches: idxString)
-                        or:[ (item textLabel matches: idxString) 
-                        or:[ (item value isSymbol and:[item value matches: idxString])]]
-                    ]
+                        (idxString match:(item nameKey ? '') )
+                        or:[ (idxString match:(item textLabel ? '')) 
+                        or:[ (item value isSymbol and:[idxString match:(item value)])]]
+                    ]  
             ] ifFalse:[
                 item := 
                     anApplicationOrViewOrMenuItem itemForWhich:[:item |
@@ -1396,16 +1409,21 @@
             ].
             foundIt ifFalse:[
                 each isMenu ifTrue:[
+                    |comp|
+
                     (item := each detectItemForNameKey:componentNameSymbol) notNil ifTrue:[
-                        foundByName add:item. foundIt := true
+                        comp := ItemInView new view:each item:item boundsInView:(item layout).
+                        foundByName add:comp. foundIt := true
                     ].
                     foundIt ifFalse:[
                         (item := each detectItemForKey:componentNameSymbol) notNil ifTrue:[
-                            foundByName add:item. foundIt := true 
+                            comp := ItemInView new view:each item:item boundsInView:(item layout).
+                            foundByName add:comp. foundIt := true 
                         ].    
                         foundIt ifFalse:[
                             (item := each detectItemForLabel:componentNameSymbol) notNil ifTrue:[
-                                foundByLabel add:item. foundIt := true 
+                                comp := ItemInView new view:each item:item boundsInView:(item layout).
+                                foundByLabel add:comp. foundIt := true 
                             ].    
                         ].
                     ].
@@ -1422,7 +1440,7 @@
             (itemsFound conform:[:each | each askFor:#isMenuItem]) ifTrue:[
                 (itemsFound collect:[:item | item itemValue]) asSet size == 1 ifTrue:[
                     "/ choose one which is visible, if possible
-                    visibleItems := itemsFound select:[:item | item menuPanel shown].
+                    visibleItems := itemsFound select:[:item | item view shown].
                     visibleItems notEmpty ifTrue:[
                         ^ visibleItems first
                     ].
@@ -1529,6 +1547,21 @@
     "Modified (comment): / 23-07-2019 / 09:32:44 / Claus Gittinger"
 !
 
+pinPOForPin:pinName ofStep:stepName
+    |diagramEditor pinPO|
+
+    (diagramEditor := lastComponent) isScrollWrapper ifTrue:[
+        diagramEditor := lastComponent scrolledView
+    ].
+    pinPO := diagramEditor 
+            detectPOForWhich:[:po |
+                po isPin 
+                and:[ po name = pinName
+                and:[ po owningStepPO name = stepName ]]
+            ].
+    ^ pinPO
+!
+
 screenBoundsOfComponent:aWidgetOrMenuItemOrTab
     |itemLayout|
 
@@ -1769,7 +1802,7 @@
     
     bounds := self screenBoundsOfComponent:aWidgetOrMenuItemOrTab.
     bounds isNil ifTrue:[
-        self error:'no bounds found for: ',aWidgetOrMenuItemOrTab printString.
+        self error:('no bounds found for: %1 (%2)' bindWith:lastComponentName with:aWidgetOrMenuItemOrTab printString).
     ].
     position := bounds center rounded.
     self movePointerToScreenPosition:position speed:pixelsPerSecond.
@@ -2261,6 +2294,10 @@
     ^ item
 !
 
+itemValue
+    ^ item itemValue
+!
+
 layout
     ^ item layout
 !