--- /dev/null 2017-11-08 15:39:21.000000000 -0800 +++ new/core/JemmyCore/doc/Jemmy3UserTutorial.html 2017-11-08 15:39:21.000000000 -0800 @@ -0,0 +1,143 @@ + + + +
+Parent<SomeControlType>
which would be some class which is aware of a set of controls of SomeControlType
type (for example, javax.swing.JButton
in Swing or javafx.scene.control.Button
in JavaFX). The set could either be hierarchical, which is typically the case - take AWT or Scenegraph or just about anything, or a plain structure - it does not matter from the usage point of view, because Parent
instance knows what is it dealing with.Parents
could be (TBD throw in some examples)Parent
, you could proceed to getting Lookup<SomeControlType>
instance by calling lookup(LookupCriteria<SomeControlType>)
method.
+ + someParent.lookup(new SomeLookupCriteria<SomeControlType>())// this gives an instance of Lookup<SomeControlType> ++ + Jemmy2
LookupCriteria
used to be called ComponentChooser
.someParent
is aware about, you, so far picked those which pass the SomeLookupCriteria
. Similarly, you could narrow the search with a LookupCriteria
and the control type:
+ + someParent.lookup(Class<SomeControlSubType>new SomeLookupCriteria<SomeControlSubType>())// this gives an instance of Lookup<SomeControlSubType> ++ where
SomeControlSubType
extends SomeControlType
Lookup<SomeControlType>
represents a set of controls, so you could proceed directly to examining one of those by index. You could use get(int)
method to get one of this. It is important to notice that the get(int)
method returns an instance of SomeControlType
, so you do not need to cast it.size()
) or ask the lookup to wait for at least a certain number of them (wait(int)
). wrap(int)
) so that you could use some test logic of dealing with the control. The wrapping will be described in details later in the tutorial.Lookup
is that it itself is a Parent<SomeControlType>
(or Parent<SomeControlSubType>
). Thus, you could proceed with narrowing down the search further with lookup(LookupCriteria)
method (or lookup(Class, LookupCriteria))
.+ someParent.lookup([Class, ]LookupCriteria)[.lookup([Class, ]LookupCriteria) ...].(get(int)|wrap()|size()|wait(int)) ++ + It is also worthy to note that, if the default abstract Jemmy Core's implementation of
Lookup
is used, the actual component hierarchy is not examined up to the moment it has to be. That is, lookup(...)
methods itself do not go through the list of controls trying to apply the criteria, when they called. It is only when one of the get(int)|wrap()|size()|wait(int)
methods called, the hierarchy is explored. Hence, there is neither memory spend for creating intermediate lists nor performance is wasted. For more info, check the Jemmy developers tutorial.wrap(int)
methods of a lookup. Naturally, the wrappers are UI library specific, so, Jemmy Core could not possible be aware about them. The library specific Jemmy Core extension is taking care about supplying them. For more info, check the Jemmy developers tutorial (TBD).Wrap<CONTROL>
class, which, itself, provides core functionality to perform mouse and keyboard operations on the control.type(String)
method for a text field of any kind. Naturally, Wrap
class itself does not have anything like this.ControlInterface
concept comes to the game. Having had a wrapper, gotten by wrap(int)
method, you could proceed to treating is as MyInterface
(which should be a class/interface implementing/extending ControlInterface
- just to have some control over it):
+ + myWrappedControl.as(MyInterface.class) /// this would be an instance of MyInterface ++ + Please consult Jemmy developers tutorial (TBD) on the ways to implement as method.
MyInterface
by calling myWrappedControl.is(MyInterface.class)
, however generally it is up to Jemmy Core extension developer which interfaces the wrapper implements.+ myWrappedControl.as(Text.class).type("some new text"); ++ + One side effect of the interfaces is that the implementations of wrappers could be private or package private, as the wrapper classes are not accessed directly from the test.
Parent<CONTROL>
which is itself an interface.is(Class interfaceClass, Class parameterClass)
and as(Class interfaceClass, Class parameterClass)
methods. It could look like this:
+ + someParent.lookup(new SomeCriteria<SomeControlType>()).wrap(0).as(Parent.class, SomeOtherControlType.class).lookup(new SomeOtherCriteria<SomeOtherControlType>).get(0) // this would give an instance of SomeOtherControlType which leaves within some instance of SomeControlType. ++ +
wait(int)
on a lookup, it waits for a given number of controls to exist which pass the criteria, when you call get(int)
or wrap(int)
, it first calls wait(int)
method to ensure that big enough number of controls are there.Waiter
supplied by Jemmy.TimeoutExpiredException
is thrown. That allows not to worry about time checking within the test itself. If something goes wrong, test will simply fail with the exception. It also allows to check the negative scenarios by catching the exception.Environment
instance.Parent
or Lookup
always have an instance of Environment
associated with it. Whenever Wrap
is created, Environment
is cloned (i.e. child Environment
is created) and assigned to the Wrap
.Wrap
(by changing its environment) or the while hierarchy (by changing Environment
associated with a Parent
).