From 56000e1aae3052a2b3a48373e0317d7d55af91aa Mon Sep 17 00:00:00 2001 From: URunDEAD Date: Wed, 3 Nov 2021 12:40:49 +0200 Subject: [PATCH] Click On Component with regexp identifier usage --- .../swing/component/ComponentOperator.java | 23 +++++- .../component/ComponentOperatorFactory.java | 4 +- .../swing/dialog/DialogOperator.java | 8 +-- .../keyword/component/ComponentKeywords.java | 70 +++++++++++++++---- .../resources/robot-tests/component.robot | 28 ++++++++ 5 files changed, 112 insertions(+), 21 deletions(-) diff --git a/src/main/java/org/robotframework/swing/component/ComponentOperator.java b/src/main/java/org/robotframework/swing/component/ComponentOperator.java index 95a0726b..20850139 100644 --- a/src/main/java/org/robotframework/swing/component/ComponentOperator.java +++ b/src/main/java/org/robotframework/swing/component/ComponentOperator.java @@ -23,13 +23,30 @@ import org.netbeans.jemmy.operators.ContainerOperator; import org.netbeans.jemmy.operators.JComponentOperator; import org.netbeans.jemmy.operators.JPopupMenuOperator; +import org.netbeans.jemmy.util.NameComponentChooser; +import org.netbeans.jemmy.util.RegExComparator; +import org.robotframework.swing.chooser.ByNameComponentChooser; +import org.robotframework.swing.common.Identifier; +import org.robotframework.swing.context.Context; import org.robotframework.swing.popup.PopupMenuOperatorFactory; import java.awt.event.InputEvent; public class ComponentOperator extends JComponentOperator { private PopupMenuOperatorFactory popupMenuOperatorFactory = new PopupMenuOperatorFactory(); - + + public static ComponentOperator newOperatorFor(int index) { + return new ComponentOperator((ContainerOperator) Context.getContext() , index); + } + + public static ComponentOperator newOperatorFor(String name) { + Identifier identifier = new Identifier(name); + if (identifier.isRegExp()) + return new ComponentOperator((ContainerOperator) Context.getContext(), + createRegExpComponentChooser(identifier.asString())); + return new ComponentOperator((ContainerOperator) Context.getContext(), new ByNameComponentChooser(name)); + } + public ComponentOperator(ContainerOperator cont, ComponentChooser chooser) { super(cont, chooser); } @@ -68,6 +85,10 @@ private int toInputEventMask(String inputEventFieldName) { } } + private static ComponentChooser createRegExpComponentChooser(String identifier) { + return new JComponentFinder(new NameComponentChooser(identifier, new RegExComparator())); + } + private int toCombinedInputEventMasks(String[] modifierStrings) { int combinedInputEventMask = 0; if (modifierStrings.length > 0) diff --git a/src/main/java/org/robotframework/swing/component/ComponentOperatorFactory.java b/src/main/java/org/robotframework/swing/component/ComponentOperatorFactory.java index b2334bd6..a981bc66 100644 --- a/src/main/java/org/robotframework/swing/component/ComponentOperatorFactory.java +++ b/src/main/java/org/robotframework/swing/component/ComponentOperatorFactory.java @@ -24,11 +24,11 @@ public class ComponentOperatorFactory extends DefaultContextVerifyingOperatorFactory { @Override public ComponentOperator createOperatorByIndex(int index) { - return new ComponentOperator((ContainerOperator) Context.getContext(), index); + return ComponentOperator.newOperatorFor(index); } @Override public ComponentOperator createOperatorByName(String name) { - return new ComponentOperator((ContainerOperator) Context.getContext(), new ByNameComponentChooser(name)); + return ComponentOperator.newOperatorFor(name); } } diff --git a/src/main/java/org/robotframework/swing/dialog/DialogOperator.java b/src/main/java/org/robotframework/swing/dialog/DialogOperator.java index f749ad13..7af03239 100644 --- a/src/main/java/org/robotframework/swing/dialog/DialogOperator.java +++ b/src/main/java/org/robotframework/swing/dialog/DialogOperator.java @@ -28,14 +28,14 @@ public class DialogOperator extends JDialogOperator implements ComponentWrapper { - public static DialogOperator newOperatorFor(int index) { - return new DialogOperator(index); - } - private DialogOperator(int index) { super(index); } + public static DialogOperator newOperatorFor(int index) { + return new DialogOperator(index); + } + public static DialogOperator newOperatorFor(String title) { Identifier identifier = new Identifier(title); if (identifier.isRegExp()) diff --git a/src/main/java/org/robotframework/swing/keyword/component/ComponentKeywords.java b/src/main/java/org/robotframework/swing/keyword/component/ComponentKeywords.java index 67e09645..eea2492f 100644 --- a/src/main/java/org/robotframework/swing/keyword/component/ComponentKeywords.java +++ b/src/main/java/org/robotframework/swing/keyword/component/ComponentKeywords.java @@ -46,8 +46,12 @@ public class ComponentKeywords { operatorFactory); @RobotKeyword("Fails if component exists within current context.\n" + + "*N.B.* Regular expression can be used to select the dialog by prefixing the identifier with ``regexp=``.\n" + + "See more details in `Regular expressions` section.\n\n" + "You might want to set the waiting timeout with the keyword `Set Jemmy Timeout`\n\n" - + "Example:\n" + "| `Component Should Not Exist` | myPanel |\n") + + "Example:\n" + + "| `Component Should Not Exist` | myPanel |\n" + + "| `Component Should Not Exist` | regexp=^A.* | No component starting with 'A' should exist |\n") @ArgumentNames({ "identifier" }) public void componentShouldNotExist(String identifier) { Assert.assertFalse("Component '" + identifier + "' exists", @@ -55,8 +59,12 @@ public void componentShouldNotExist(String identifier) { } @RobotKeyword("Fails if component does not exist within current context.\n" + + "*N.B.* Regular expression can be used to select the dialog by prefixing the identifier with ``regexp=``.\n" + + "See more details in `Regular expressions` section.\n\n" + "You might want to set the waiting timeout with the keyword `Set Jemmy Timeout`\n\n" - + "Example:\n" + "| `Component Should Not Exist` | myPanel |\n") + + "Example:\n" + + "| `Component Should Exist` | myPanel |\n" + + "| `Component Should Exist` | regexp=^A.* | There should be a component starting with 'A' |\n") @ArgumentNames({ "identifier" }) public void componentShouldExist(String identifier) { Assert.assertTrue("Component '" + identifier + "' does not exist", @@ -64,13 +72,16 @@ public void componentShouldExist(String identifier) { } @RobotKeyword("Clicks on a component, optionally using click count, a specific mouse button and keyboard modifiers.\n\n" + + "*N.B.* Regular expression can be used to select the dialog by prefixing the identifier with ``regexp=``.\n" + + "See more details in `Regular expressions` section.\n\n" + "The codes used for mouse button and key modifiers are the field names from ``java.awt.event.InputEvent``. " + "For example: ``BUTTON1_MASK``, ``CTRL_MASK``, ``ALT_MASK``, ``ALT_GRAPH_MASK``, ``SHIFT_MASK``, and ``META_MASK``.\n\n" + "*Note:* Some keys have more convinient case insensitive aliases that can be used: ``LEFT BUTTON``, ``RIGHT BUTTON``, ``SHIFT``, " + "``CTRL``, ``ALT``, ``META``\n\n" + "Examples:\n" + "| `Click On Component` | myComponent | # Double clicks with mouse button 2 on the component ... |\n" - + "| ... | 2 | RIGHT BUTTON | ALT | # ... while holding down the ALT key |\n") + + "| ... | 2 | RIGHT BUTTON | ALT | # ... while holding down the ALT key |\n" + + "| `Click On Component` | regexp=^A.* | #Clicks with mouse button on a component starting with 'A' ... |\n") @ArgumentNames({ "identifier", "clickCountString=1", "buttonString=BUTTON1_MASK", "*keyModifierStrings" }) public void clickOnComponent(String identifier, String clickCountString, String buttonString, String... args) { OptionalArgsForTableCellAndComponentClicking optArgs = new OptionalArgsForTableCellAndComponentClicking(clickCountString, buttonString, args); @@ -80,15 +91,24 @@ public void clickOnComponent(String identifier, String clickCountString, String optArgs.keyModifiers()); } - @RobotKeyword("Right clicks on a component.\n\n" + "Example:\n" - + "| `Right Click On Component` | myComponent |") + @RobotKeyword("Right clicks on a component.\n\n" + + "*N.B.* Regular expression can be used to select the dialog by prefixing the identifier with ``regexp=``.\n" + + "See more details in `Regular expressions` section.\n\n" + + "Example:\n" + + "| `Right Click On Component` | myComponent |" + + "| `Right Click On Component` | regexp=^A.* | #Right clicks on a component starting with 'A'") @ArgumentNames({ "identifier" }) public void rightClickOnComponent(String identifier) { operator(identifier).clickMouse(1, InputEvent.BUTTON3_MASK); } - @RobotKeyword("Returns the component's tooltip text.\n\n" + "Example:\n" + @RobotKeyword("Returns the component's tooltip text.\n\n" + + "*N.B.* Regular expression can be used to select the dialog by prefixing the identifier with ``regexp=``.\n" + + "See more details in `Regular expressions` section.\n\n" + + "Example:\n" + "| ${tooltip}= | `Get Tooltip Text` | saveButton |\n" + + "| `Should Be Equal` | Save | ${tooltip} |\n" + + "| ${tooltip}= | `Get Tooltip Text` | regexp=^A.* |\n" + "| `Should Be Equal` | Save | ${tooltip} |\n") @ArgumentNames({ "identifier" }) public String getTooltipText(String identifier) { @@ -99,6 +119,7 @@ public String getTooltipText(String identifier) { + "Useful for example when sending keyboard events to a component.\n\n" + "Example:\n" + "| `Focus To Component` | myTextField | | |\n" + + "| `Focus To Component` | regexp=^A.* | | |\n" + "| `Send Keyboard Event` | VK_C | CTRL_MASK | # paste from clipboard |\n") @ArgumentNames({ "identifier" }) public void focusToComponent(String identifier) { @@ -106,9 +127,12 @@ public void focusToComponent(String identifier) { } @RobotKeyword("Selects an item from the components context popup menu.\n" + + "*N.B.* Regular expression can be used to select the dialog by prefixing the identifier with ``regexp=``.\n" + + "See more details in `Regular expressions` section.\n\n" + "Does a right click on the component and selects the specified menu item from the popup menu.\n\n" + "Example:\n" - + "| `Select From Popup Menu` | myComponent | Actions | Do something |\n") + + "| `Select From Popup Menu` | myComponent | Actions | Do something |\n" + + "| `Select From Popup Menu` | regexp=^A.* | Actions | Do something |\n") @ArgumentNames({ "identifier", "menuPath" }) public void selectFromPopupMenu(String identifier, String menuPath) { JPopupMenuOperator popup = operator(identifier).invokePopup(); @@ -116,9 +140,12 @@ public void selectFromPopupMenu(String identifier, String menuPath) { } @RobotKeyword("Gets item names from the components context popup menu.\n" + + "*N.B.* Regular expression can be used to select the dialog by prefixing the identifier with ``regexp=``.\n" + + "See more details in `Regular expressions` section.\n\n" + "Does a right click on the component and retrieves the specified menu items from the popup menu.\n\n" + "Example:\n" + "| @{items}= | `Get Menu Items From Popup Menu` | myComponent | Actions |\n" + + "| @{items}= | `Get Menu Items From Popup Menu` | regexp=^A.* | Actions |\n" + "| `Should Contain` | ${items} | Do something |") @ArgumentNames({ "identifier", "menuPath" }) public List getMenuItemsFromPopupMenu(final String identifier, final String menuPath) { @@ -132,9 +159,12 @@ public List getMenuItemsFromPopupMenu(final String identifier, final Str } @RobotKeyword("Checks that component is visible.\n" + + "*N.B.* Regular expression can be used to select the dialog by prefixing the identifier with ``regexp=``.\n" + + "See more details in `Regular expressions` section.\n\n" +"Even if one pixel of the component is visible, this keyword will pass.\n\n" +"Example:\n" - + "| `Component Should Be Visible` | myComponent |\n") + + "| `Component Should Be Visible` | myComponent |\n" + + "| `Component Should Be Visible` | regexp=^A.* |\n") @ArgumentNames({ "identifier"}) public void componentShouldBeVisible(String identifier) { Rectangle visible = operator(identifier).getVisibleRect(); @@ -142,9 +172,12 @@ public void componentShouldBeVisible(String identifier) { } @RobotKeyword("Checks that component is not visible.\n" + + "*N.B.* Regular expression can be used to select the dialog by prefixing the identifier with ``regexp=``.\n" + + "See more details in `Regular expressions` section.\n\n" +"Fails if even one pixel of the component is visible.\n\n" +"Example:\n" - + "| `Component Should Not Be Visible` | myComponent |\n") + + "| `Component Should Not Be Visible` | myComponent |\n" + + "| `Component Should Not Be Visible` | regexp=^A.* |\n") @ArgumentNames({ "identifier"}) public void componentShouldNotBeVisible(String identifier) { Rectangle visible = operator(identifier).getVisibleRect(); @@ -152,18 +185,24 @@ public void componentShouldNotBeVisible(String identifier) { } @RobotKeyword("Scrolls component to view.\n\n" + + "*N.B.* Regular expression can be used to select the dialog by prefixing the identifier with ``regexp=``.\n" + + "See more details in `Regular expressions` section.\n\n" +"Example:\n" - + "| `Scroll Component To View` | myComponent |\n") + + "| `Scroll Component To View` | myComponent |\n" + + "| `Scroll Component To View` | regexp=^A.* |\n") @ArgumentNames({ "identifier"}) public void scrollComponentToView(String identifier) { operator(identifier).scrollRectToVisible(new Rectangle(100, 100)); } @RobotKeyword("List methods of components object.\n" + + "*N.B.* Regular expression can be used to select the dialog by prefixing the identifier with ``regexp=``.\n" + + "See more details in `Regular expressions` section.\n\n" +"When working with custom components you may use this keyword to discover methods you can call " +"with `Call Component Method` keyword.\n\n" +"Example:\n" - + "| `List Component Methods` | myComponent |\n") + + "| `List Component Methods` | myComponent |\n" + + "| `List Component Methods` | regexp=^A.* |\n") @ArgumentNames({"identifier"}) public String[] listComponentMethods(String identifier) { Class klass = operator(identifier).getSource().getClass(); @@ -217,9 +256,12 @@ public static List getParameterNames(Method method) { } @RobotKeyword("Calls a method from specified component.\n\n" - + "Arguments are automatically converted if possible to type expected by the method.\n\n" - + "Example:\n" - + "| `Call Component Method` | buttonId | setToolTipText | new tooltip text |") + + "*N.B.* Regular expression can be used to select the dialog by prefixing the identifier with ``regexp=``.\n" + + "See more details in `Regular expressions` section.\n\n" + + "Arguments are automatically converted if possible to type expected by the method.\n\n" + + "Example:\n" + + "| `Call Component Method` | buttonId | setToolTipText | new tooltip text |" + + "| `Call Component Method` | regexp=^A.* | setToolTipText | new tooltip text |") @ArgumentNames({"identifier", "method", "*args"}) public Object callComponentMethod(String identifier, String method, String... args) { Object component = operator(identifier).getSource(); diff --git a/src/test/resources/robot-tests/component.robot b/src/test/resources/robot-tests/component.robot index 04a6ddf5..0861fb68 100644 --- a/src/test/resources/robot-tests/component.robot +++ b/src/test/resources/robot-tests/component.robot @@ -7,7 +7,9 @@ Variables platform_info.py ${textAreaName} testTextArea ${textFieldName} testTextField ${componentName} Main Panel +${regexComponentName} M.in Pa*n.l ${buttonName} testButton +${regexButtonName} te.tB*ut*on *** Test Cases *** Sets Focus @@ -28,6 +30,9 @@ Component Should Exist By Index Component Should Exist By Name componentShouldExist ${componentName} +Component Should Exist By Name Using RegExp + componentShouldExist regexp=${regexComponentName} + Component Should Exist Fails If The Component Doesn't Exist runKeywordAndExpectError *Component 'Unexisting component' does not exist* componentShouldExist Unexisting component runKeywordAndExpectError *Component '9999' does not exist* componentShouldExist 9999 @@ -38,6 +43,9 @@ Component Should Not Exist By Index Component Should Not Exist By Name componentShouldNotExist Unexisting component +Component Should Not Exist By Name Using RegExp + componentShouldNotExist regexp=Unex.st*ing compo.ent + Component Should Not Exist Fails If The Component Exists runKeywordAndExpectError *Component '${componentName}' exists* componentShouldNotExist ${componentName} runKeywordAndExpectError *Component '0' exists* componentShouldNotExist 0 @@ -48,6 +56,12 @@ Click On Component ${text}= getButtonText ${buttonName} shouldBeEqual Button Was Pushed1 ${text} +Click On Component Using RegExp + [Setup] resetButton + clickOnComponent regexp=t.stBut*.n + ${text}= getButtonText ${buttonName} + shouldBeEqual Button Was Pushed1 ${text} + Doubleclick On Component [Setup] resetButton doubleClickOnComponent testButton @@ -70,16 +84,30 @@ Get Tooltip Text ${tooltip}= getToolTipText testLabel shouldBeEqual TEST LABEL ${tooltip} +Get Tooltip Text Using RegExp + ${tooltip}= getToolTipText regexp=te.tLa*bel + shouldBeEqual TEST LABEL ${tooltip} + List Component Methods ${methods}= listComponentMethods ${buttonName} listShouldContainValue ${methods} java.lang.String getToolTipText() +List Component Methods Using RegExp + ${methods}= listComponentMethods regexp=${regexButtonName} + listShouldContainValue ${methods} java.lang.String getToolTipText() + Call Component Method ${tooltipText}= setVariable tooltip test callComponentMethod ${buttonName} setToolTipText ${tooltipText} ${tooltipValue}= callComponentMethod ${buttonName} getToolTipText Should Be Equal ${tooltipText} ${tooltipValue} +Call Component Method Using RegExp + ${tooltipText}= setVariable tooltip test + callComponentMethod regexp=${regexButtonName} setToolTipText ${tooltipText} + ${tooltipValue}= callComponentMethod ${buttonName} getToolTipText + Should Be Equal ${tooltipText} ${tooltipValue} + *** Keywords *** resetButton setButtonText ${buttonName} Test Button