diff --git a/CHANGELOG b/CHANGELOG index d21b346f9..9c9e5b39b 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,10 @@ +#TESTAR v2.8.6 (24-Mar-2026) +- Remove linux AtSpi subproject +- Remove unused Tags +- Refactor custom interfaces with Java functions +- Refactor ProtocolUtil and add ScreenshotProvider + + #TESTAR v2.8.5 (17-Mar-2026) - Bump io.appium:java-client from 10.0.0 to 10.1.0 - Update JS getIsBlockedTestar logic diff --git a/VERSION b/VERSION index 7f04bb11e..adaf203ac 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.8.5 \ No newline at end of file +2.8.6 \ No newline at end of file diff --git a/android/src/org/testar/monkey/alayer/android/AndroidProtocolUtil.java b/android/src/org/testar/monkey/alayer/android/AndroidProtocolUtil.java deleted file mode 100644 index d374630d8..000000000 --- a/android/src/org/testar/monkey/alayer/android/AndroidProtocolUtil.java +++ /dev/null @@ -1,156 +0,0 @@ -/*************************************************************************************************** - * - * Copyright (c) 2020 - 2024 Universitat Politecnica de Valencia - www.upv.es - * Copyright (c) 2020 - 2024 Open Universiteit - www.ou.nl - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holder nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *******************************************************************************************************/ - -package org.testar.monkey.alayer.android; - -import org.testar.ProtocolUtil; -import org.testar.monkey.Pair; -import org.testar.monkey.alayer.*; -import org.testar.monkey.alayer.android.enums.AndroidTags; - -import java.io.IOException; -import java.util.ArrayList; - -public class AndroidProtocolUtil extends ProtocolUtil { - - public static String getActionshot(State state, Action action) { - try { - return org.testar.monkey.alayer.android.AndroidAppiumFramework.getScreenshotAction(state, action); - } catch(Exception e) { - System.err.println("Exception when taking action screenshot: " + e); - } - - return ProtocolUtil.getActionshot(state, action); - } - - public static String getStateshot(State state) { - try { - return AndroidAppiumFramework.getScreenshotState(state); - } catch(Exception e) { - System.err.println("Exception occured when trying to take a screenshot of the Android emulator: " + e); - } - - return ProtocolUtil.getStateshot(state); - } - - public static String getStateshotSpyMode(State state) { - try { - return org.testar.monkey.alayer.android.AndroidAppiumFramework.getScreenshotSpyMode(state.get(Tags.ConcreteID, "NoConcreteIdAvailable")); - } catch(Exception e) { - System.err.println("Exception occured when trying to take a screenshot of the Android emulator: " + e); - } - - return ProtocolUtil.getStateshot(state); - } - - /** - * Method returns a binary representation of a state's screenshot. - * @param state - * @return - */ - public static AWTCanvas getStateshotBinary(State state) { - // Obtain the binary screenshotfile through the appium driver. - try { - return AndroidAppiumFramework.getScreenshotBinary(state); - } catch (IOException e) { - System.err.println("Exception occured when trying to take a binary screenshot of the Android emulator: " + e); - } - - return ProtocolUtil.getStateshotBinary(state); - } - - public static String getCurrentPackage() { - return AndroidAppiumFramework.getCurrentPackage(); - } - - // Method which constructs the hierarchy xpath (absolute path) - // This method is needed as this is the only way to uniquely identify an GUI object if it has no accessibilityID. - public static String constructXpath(Widget w) { - StringBuilder sb = new StringBuilder(); - Widget parentWidget = w; - - while (parentWidget != w.root()) { - String classTag = parentWidget.get(Tags.Desc); - int indexNumber = parentWidget.get(AndroidTags.AndroidNodeIndex); - - if (classTag.equals("Root")) { - break; - } - - parentWidget = parentWidget.parent(); - - ArrayList> childClasses = new ArrayList>(); - - for (int i = 0; i < parentWidget.childCount(); i++) { - childClasses.add(new Pair(parentWidget.child(i).get(Tags.Desc), parentWidget.child(i).get(AndroidTags.AndroidNodeIndex))); - } - - boolean checkDoubles = false; - boolean incCounter = true; - int counterOccur = 1; - for (Pair childClass : childClasses) { - String leftSide = (String) childClass.left(); - int rightSide = (int) childClass.right(); - if (leftSide.equals(classTag) && rightSide != indexNumber) { - checkDoubles = true; - if (incCounter) { - counterOccur++; - } - } - else if (leftSide.equals(classTag) && rightSide == indexNumber) { - incCounter = false; - } - } - - if (checkDoubles) { - String xpathComponent = "/" + classTag + "[" + counterOccur + "]"; - sb.insert(0, xpathComponent); - } - else { - String xpathComponent = "/" + classTag; - sb.insert(0, xpathComponent); - } - - } - - sb.insert(0, "/hierarchy"); - - return sb.toString(); - } - - public static boolean resolveEscapedApplication(String originalPackage) { - AndroidAppiumFramework.clickBackButton(); - String currentState = AndroidAppiumFramework.getCurrentPackage(); - if (!originalPackage.equals(currentState)) { - return false; - } - return true; - } -} diff --git a/android/src/org/testar/monkey/alayer/android/AndroidStateFetcher.java b/android/src/org/testar/monkey/alayer/android/AndroidStateFetcher.java index 8765d35c3..fecebb739 100644 --- a/android/src/org/testar/monkey/alayer/android/AndroidStateFetcher.java +++ b/android/src/org/testar/monkey/alayer/android/AndroidStateFetcher.java @@ -35,6 +35,7 @@ import org.testar.monkey.alayer.exceptions.StateBuildException; import org.testar.monkey.alayer.android.enums.AndroidTags; import org.testar.monkey.alayer.android.util.AndroidNodeParser; +import org.testar.monkey.alayer.android.util.AndroidXpathUtil; import org.w3c.dom.Document; import org.w3c.dom.Node; @@ -82,7 +83,7 @@ public AndroidState call() throws Exception { // After create the widget tree, set widgets Path for (Widget w : root) { w.set(Tags.Path, Util.indexString(w)); - w.set(AndroidTags.AndroidXpath, AndroidProtocolUtil.constructXpath(w)); + w.set(AndroidTags.AndroidXpath, AndroidXpathUtil.constructXpath(w)); } return root; diff --git a/android/src/org/testar/monkey/alayer/android/spy_visualization/MobileVisualizationAndroid.java b/android/src/org/testar/monkey/alayer/android/spy_visualization/MobileVisualizationAndroid.java index da9fa62ce..e4853bdd4 100644 --- a/android/src/org/testar/monkey/alayer/android/spy_visualization/MobileVisualizationAndroid.java +++ b/android/src/org/testar/monkey/alayer/android/spy_visualization/MobileVisualizationAndroid.java @@ -1,7 +1,7 @@ /*************************************************************************************************** * - * Copyright (c) 2020 - 2025 Open Universiteit - www.ou.nl - * Copyright (c) 2020 - 2025 Universitat Politecnica de Valencia - www.upv.es + * Copyright (c) 2020 - 2026 Open Universiteit - www.ou.nl + * Copyright (c) 2020 - 2026 Universitat Politecnica de Valencia - www.upv.es * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -32,7 +32,7 @@ import org.testar.monkey.alayer.Action; import org.testar.monkey.alayer.State; -import org.testar.monkey.alayer.android.AndroidProtocolUtil; +import org.testar.monkey.alayer.android.util.AndroidScreenshotUtil; import javax.swing.*; import java.awt.event.ActionEvent; @@ -138,7 +138,7 @@ public void actionPerformed(ActionEvent actionEvent) { /** Method called when the overlay needs to be updated when the state changes. */ private void updateScreen() { // Updates screenshot and overlay - String screenshotPath = AndroidProtocolUtil.getStateshotSpyMode(usedState); + String screenshotPath = AndroidScreenshotUtil.getStateshotSpyMode(usedState); imagePanel.updateSc(screenshotPath, treeVizInstance.tree, deriveActionsFunction.apply(usedState)); frame.revalidate(); diff --git a/android/src/org/testar/monkey/alayer/android/util/AndroidScreenshotUtil.java b/android/src/org/testar/monkey/alayer/android/util/AndroidScreenshotUtil.java new file mode 100644 index 000000000..85ccc2969 --- /dev/null +++ b/android/src/org/testar/monkey/alayer/android/util/AndroidScreenshotUtil.java @@ -0,0 +1,87 @@ +/*************************************************************************************************** + * + * Copyright (c) 2020 - 2026 Universitat Politecnica de Valencia - www.upv.es + * Copyright (c) 2020 - 2026 Open Universiteit - www.ou.nl + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *******************************************************************************************************/ + +package org.testar.monkey.alayer.android.util; + +import java.io.IOException; +import java.util.Objects; + +import org.testar.monkey.alayer.AWTCanvas; +import org.testar.monkey.alayer.Action; +import org.testar.monkey.alayer.State; +import org.testar.monkey.alayer.Tags; +import org.testar.monkey.alayer.android.AndroidAppiumFramework; +import org.testar.util.ScreenshotUtil; + +public class AndroidScreenshotUtil { + + private AndroidScreenshotUtil() { + } + + public static String getActionshot(State state, Action action) { + Objects.requireNonNull(state, "State cannot be null"); + Objects.requireNonNull(action, "Action cannot be null"); + try { + return AndroidAppiumFramework.getScreenshotAction(state, action); + } catch(Exception e) { + System.err.println("Exception when taking action screenshot: " + e); + } + + return ""; + } + + public static String getStateshotSpyMode(State state) { + Objects.requireNonNull(state, "State cannot be null"); + try { + return AndroidAppiumFramework.getScreenshotSpyMode(state.get(Tags.ConcreteID, "NoConcreteIdAvailable")); + } catch(Exception e) { + System.err.println("Exception occured when trying to take a screenshot of the Android emulator: " + e); + } + + return ""; + } + + /** + * Method returns a binary representation of a state's screenshot. + * @param state + * @return + */ + public static AWTCanvas getStateshotBinary(State state) { + Objects.requireNonNull(state, "State cannot be null"); + try { + return AndroidAppiumFramework.getScreenshotBinary(state); + } catch (IOException e) { + System.err.println("Exception occured when trying to take a binary screenshot of the Android emulator: " + e); + } + + return ScreenshotUtil.getStateshotBinary(state); + } + +} diff --git a/android/src/org/testar/monkey/alayer/android/util/AndroidXpathUtil.java b/android/src/org/testar/monkey/alayer/android/util/AndroidXpathUtil.java new file mode 100644 index 000000000..f68514240 --- /dev/null +++ b/android/src/org/testar/monkey/alayer/android/util/AndroidXpathUtil.java @@ -0,0 +1,104 @@ +/*************************************************************************************************** + * + * Copyright (c) 2020 - 2026 Universitat Politecnica de Valencia - www.upv.es + * Copyright (c) 2020 - 2026 Open Universiteit - www.ou.nl + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *******************************************************************************************************/ + +package org.testar.monkey.alayer.android.util; + +import java.util.ArrayList; + +import org.testar.monkey.Pair; +import org.testar.monkey.alayer.Tags; +import org.testar.monkey.alayer.Widget; +import org.testar.monkey.alayer.android.enums.AndroidTags; + +public class AndroidXpathUtil { + + private AndroidXpathUtil() { + } + + + // Method which constructs the hierarchy xpath (absolute path) + // This method is needed as this is the only way to uniquely identify an GUI object if it has no accessibilityID. + public static String constructXpath(Widget w) { + StringBuilder sb = new StringBuilder(); + Widget parentWidget = w; + + while (parentWidget != w.root()) { + String classTag = parentWidget.get(Tags.Desc, "*"); + int indexNumber = parentWidget.get(AndroidTags.AndroidNodeIndex, -1); + + if (classTag.equals("Root")) { + break; + } + + parentWidget = parentWidget.parent(); + + ArrayList> childClasses = new ArrayList>(); + + for (int i = 0; i < parentWidget.childCount(); i++) { + childClasses.add(new Pair( + parentWidget.child(i).get(Tags.Desc, "*"), + parentWidget.child(i).get(AndroidTags.AndroidNodeIndex, -1) + )); + } + + boolean checkDoubles = false; + boolean incCounter = true; + int counterOccur = 1; + for (Pair childClass : childClasses) { + String leftSide = (String) childClass.left(); + int rightSide = (int) childClass.right(); + if (leftSide.equals(classTag) && rightSide != indexNumber) { + checkDoubles = true; + if (incCounter) { + counterOccur++; + } + } + else if (leftSide.equals(classTag) && rightSide == indexNumber) { + incCounter = false; + } + } + + if (checkDoubles) { + String xpathComponent = "/" + classTag + "[" + counterOccur + "]"; + sb.insert(0, xpathComponent); + } + else { + String xpathComponent = "/" + classTag; + sb.insert(0, xpathComponent); + } + + } + + sb.insert(0, "/hierarchy"); + + return sb.toString(); + } + +} diff --git a/android/test/org/testar/monkey/alayer/android/util/AndroidScreenshotUtilTest.java b/android/test/org/testar/monkey/alayer/android/util/AndroidScreenshotUtilTest.java new file mode 100644 index 000000000..a32c70548 --- /dev/null +++ b/android/test/org/testar/monkey/alayer/android/util/AndroidScreenshotUtilTest.java @@ -0,0 +1,90 @@ +package org.testar.monkey.alayer.android.util; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.fail; +import static org.mockito.Mockito.mock; + +import java.io.IOException; + +import org.junit.Test; +import org.mockito.MockedStatic; +import org.mockito.Mockito; +import org.testar.monkey.alayer.AWTCanvas; +import org.testar.monkey.alayer.Action; +import org.testar.monkey.alayer.State; +import org.testar.monkey.alayer.android.AndroidAppiumFramework; +import org.testar.util.ScreenshotUtil; + +public class AndroidScreenshotUtilTest { + + @Test + public void getStateshotSpyMode_NullStateThrows() { + try { + AndroidScreenshotUtil.getStateshotSpyMode(null); + fail("Expected NullPointerException"); + } catch (NullPointerException expected) { + assertEquals("State cannot be null", expected.getMessage()); + } + } + + @Test + public void getStateshotBinary_NullStateThrows() { + try { + AndroidScreenshotUtil.getStateshotBinary(null); + fail("Expected NullPointerException"); + } catch (NullPointerException expected) { + assertEquals("State cannot be null", expected.getMessage()); + } + } + + @Test + public void getActionshot_NullStateThrows() { + Action action = mock(Action.class); + try { + AndroidScreenshotUtil.getActionshot(null, action); + fail("Expected NullPointerException"); + } catch (NullPointerException expected) { + assertEquals("State cannot be null", expected.getMessage()); + } + } + + @Test + public void getActionshot_NullActionThrows() { + State state = mock(State.class); + try { + AndroidScreenshotUtil.getActionshot(state, null); + fail("Expected NullPointerException"); + } catch (NullPointerException expected) { + assertEquals("Action cannot be null", expected.getMessage()); + } + } + + @Test + public void getActionshot_FrameworkExceptionReturnsEmptyString() { + State state = mock(State.class); + Action action = mock(Action.class); + + try (MockedStatic framework = Mockito.mockStatic(AndroidAppiumFramework.class)) { + framework.when(() -> AndroidAppiumFramework.getScreenshotAction(state, action)).thenThrow(new RuntimeException("exception")); + + String result = AndroidScreenshotUtil.getActionshot(state, action); + assertEquals("", result); + } + } + + @Test + public void getStateshotBinary_FallbackWhenFrameworkThrows() { + State state = mock(State.class); + AWTCanvas expected = mock(AWTCanvas.class); + + try (MockedStatic framework = Mockito.mockStatic(AndroidAppiumFramework.class); + MockedStatic coreUtil = Mockito.mockStatic(ScreenshotUtil.class)) { + framework.when(() -> AndroidAppiumFramework.getScreenshotBinary(state)).thenThrow(new IOException("exception")); + coreUtil.when(() -> ScreenshotUtil.getStateshotBinary(state)).thenReturn(expected); + + AWTCanvas result = AndroidScreenshotUtil.getStateshotBinary(state); + assertSame(expected, result); + } + } +} diff --git a/android/test/org/testar/monkey/alayer/android/util/AndroidXpathUtilTest.java b/android/test/org/testar/monkey/alayer/android/util/AndroidXpathUtilTest.java new file mode 100644 index 000000000..027023039 --- /dev/null +++ b/android/test/org/testar/monkey/alayer/android/util/AndroidXpathUtilTest.java @@ -0,0 +1,70 @@ +package org.testar.monkey.alayer.android.util; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; +import org.testar.monkey.alayer.Tags; +import org.testar.monkey.alayer.android.enums.AndroidTags; +import org.testar.stub.StateStub; +import org.testar.stub.WidgetStub; + +public class AndroidXpathUtilTest { + + @Test + public void constructAndroidXpath_IndexForDuplicates() { + StateStub root = new StateStub(); + WidgetStub container = new WidgetStub(); + WidgetStub target = new WidgetStub(); + WidgetStub sibling = new WidgetStub(); + + root.addChild(container); + container.setParent(root); + root.set(Tags.Desc, "Root"); + root.set(AndroidTags.AndroidNodeIndex, 0); + + container.addChild(sibling); + container.addChild(target); + sibling.setParent(container); + target.setParent(container); + container.set(Tags.Desc, "LinearLayout"); + container.set(AndroidTags.AndroidNodeIndex, 1); + + sibling.set(Tags.Desc, "Button"); + sibling.set(AndroidTags.AndroidNodeIndex, 1); + + target.set(Tags.Desc, "Button"); + target.set(AndroidTags.AndroidNodeIndex, 2); + + String xpath = AndroidXpathUtil.constructXpath(target); + + assertEquals("/hierarchy/LinearLayout/Button[2]", xpath); + } + + @Test + public void constructAndroidXpath_EmptyDesc() { + StateStub root = new StateStub(); + WidgetStub target = new WidgetStub(); + root.addChild(target); + target.setParent(root); + // Keep Desc unset on purpose + + String xpath = AndroidXpathUtil.constructXpath(target); + + assertEquals("/hierarchy/*", xpath); + } + + @Test + public void constructAndroidXpath_EmptyNodeIndex() { + StateStub root = new StateStub(); + WidgetStub target = new WidgetStub(); + root.addChild(target); + target.setParent(root); + target.set(Tags.Desc, "Button"); + // Keep AndroidNodeIndex unset on purpose + + String xpath = AndroidXpathUtil.constructXpath(target); + + assertEquals("/hierarchy/Button", xpath); + } + +} diff --git a/config/checkstyle/checkstyle.xml b/config/checkstyle/checkstyle.xml index 08bb211c8..7e40cc29b 100644 --- a/config/checkstyle/checkstyle.xml +++ b/config/checkstyle/checkstyle.xml @@ -56,11 +56,11 @@ diff --git a/core/src/org/testar/ProtocolUtil.java b/core/src/org/testar/ProtocolUtil.java deleted file mode 100644 index e72aa47f7..000000000 --- a/core/src/org/testar/ProtocolUtil.java +++ /dev/null @@ -1,344 +0,0 @@ -/*************************************************************************************************** -* -* Copyright (c) 2016 - 2026 Universitat Politecnica de Valencia - www.upv.es -* Copyright (c) 2019 - 2026 Open Universiteit - www.ou.nl -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, -* this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the copyright holder nor the names of its -* contributors may be used to endorse or promote products derived from -* this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -* POSSIBILITY OF SUCH DAMAGE. -*******************************************************************************************************/ - -package org.testar; - -import org.testar.serialisation.ScreenshotSerialiser; -import org.testar.monkey.Util; -import org.testar.monkey.alayer.AWTCanvas; -import org.testar.monkey.alayer.Action; -import org.testar.monkey.alayer.Canvas; -import org.testar.monkey.alayer.Color; -import org.testar.monkey.alayer.FillPattern; -import org.testar.monkey.alayer.Finder; -import org.testar.monkey.alayer.Pen; -import org.testar.monkey.alayer.Rect; -import org.testar.monkey.alayer.Role; -import org.testar.monkey.alayer.SUT; -import org.testar.monkey.alayer.Shape; -import org.testar.monkey.alayer.State; -import org.testar.monkey.alayer.Tags; -import org.testar.monkey.alayer.Verdict; -import org.testar.monkey.alayer.Widget; - -import java.awt.*; -import java.util.Collections; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.List; - -/** - * Utility class to enhance TESTAR protocol. - */ -public class ProtocolUtil { - - // ################### - // Ancestors marking - // ################### - - public static LinkedHashMap ancestorsMarkingColors = new LinkedHashMap(){ - private static final long serialVersionUID = 8186743549563447423L; - { - put("1. === black", Color.from( 0, 0, 0, 255)); - put("2. === white", Color.from(255, 255, 255, 255)); - put("3. === red", Color.from(255, 0, 0, 255)); - put("4. === blue", Color.from( 0, 0, 255, 255)); - put("5. === yellow", Color.from(255, 255, 0, 255)); - put("6. === cyan", Color.from( 0, 255, 255, 255)); - put("7. === magenta", Color.from(255, 0, 255, 255)); - put("8. === green", Color.from( 0, 128, 0, 255)); - put("9. === bluesky", Color.from( 0, 128, 255, 255)); - put("a. === purple", Color.from(128, 0, 128, 255)); - put("b. === orange", Color.from(255, 128, 0, 255)); - put("c. === brown", Color.from(139, 69, 19, 255)); - put("d. === silver", Color.from(192, 192, 192, 255)); - put("e. === navy", Color.from( 0, 0, 128, 255)); - put("f. === gray", Color.from(128, 128, 128, 255)); - }}; - - public static int markParents(Canvas canvas ,Widget w, Iterator it, int lvl, boolean print){ - Widget parent; - if (!it.hasNext() || // marking colors exhausted - (parent = w.parent()) == null) - return lvl; - int margin = 4; - String colorS = it.next(); - Pen mark = Pen.newPen().setColor(ancestorsMarkingColors.get(colorS)) - .setFillPattern(FillPattern.Stroke).build(); - Shape shape = parent.get(Tags.Shape, null); - try{ - shape = Rect.from(shape.x()+lvl*margin, shape.y()+lvl*margin, - shape.width()-lvl*margin*2, shape.height()-lvl*margin*2); - }catch(java.lang.IllegalArgumentException e){}; - shape.paint(canvas, mark); - - if (print) - System.out.println("Ancestor(" + colorS + "):\n" + w.getRepresentation("\t")); - - return markParents(canvas,parent,it,lvl+1,print); - } - - // ###################### - // Widget tree renderer - // ###################### - - private static void colorShadowText(Canvas canvas, Pen pen, Pen shadowPen, double x, double y, String text){ - canvas.text(shadowPen,x+1,y+1,0,text); - canvas.text(pen,x,y,0,text); - } - - private static String briefRepresentation(Widget widget){ - String briefS = ""; - Role role = widget.get(Tags.Role, null); - if (role != null) - briefS += "ROLE: " + role.toString(); - String title = widget.get(Tags.Title, null); - if (title != null) - briefS += ", TITLE: " + title; - return briefS; - } - - public static int[] drawWidgetTree(SUT system, Canvas canvas, int x, int y, Widget wtWidget, Widget cursorWidget, int printedIDs){ - final int WIDGET_TREE_NODE_WIDTH = 1, WIDGET_TREE_NODE_HEIGHT = 16; - final int FONT_SIZE = 12; //(int)Pen.PEN_WHITE_TEXT_12px.fontSize().doubleValue(); - int nw = WIDGET_TREE_NODE_WIDTH, nh = WIDGET_TREE_NODE_HEIGHT; - boolean isRoot = (wtWidget.parent() == null), - isCursor = wtWidget == cursorWidget, - isAncestor = Util.isAncestorOf(wtWidget, cursorWidget); - if (isCursor || isAncestor){ - nw = WIDGET_TREE_NODE_HEIGHT / 2; - printedIDs++; - int printY = y + nh + 1 + printedIDs * FONT_SIZE; - canvas.rect((isCursor ? Pen.PEN_BLUE_FILL : (isRoot ? Pen.PEN_RED_FILL : Pen.PEN_GREEN_FILL)), x, y, nw, nh+1); - if (isRoot) - colorShadowText(canvas, Pen.PEN_RED_TEXT_12px, Pen.PEN_WHITE_TEXT_12px, x + nh, y, system.getStatus()); - else { - canvas.line((isCursor ? Pen.PEN_BLUE_1px_ALPHA : Pen.PEN_GREEN_1px_ALPHA), x, y + nh + 1, x, printY); - canvas.rect((isCursor ? Pen.PEN_BLUE_FILL : Pen.PEN_GREEN_FILL), - (isCursor ? FONT_SIZE : x - nw/2), - printY, nw, FONT_SIZE); - if (isCursor) - canvas.line(Pen.PEN_BLUE_1px, FONT_SIZE, printY, x, printY); - colorShadowText(canvas,(isCursor ? Pen.PEN_BLUE_TEXT_12px : Pen.PEN_GREEN_TEXT_12px), Pen.PEN_WHITE_TEXT_12px, - (isCursor ? FONT_SIZE + nw : x + nw), printY, - (isCursor ? wtWidget.getRepresentation("") : - wtWidget.get(Tags.ConcreteID) + - " (" + briefRepresentation(wtWidget) + ")")); - } - } else - canvas.line(Pen.PEN_WHITE_1px, x, y, x, y + nh); - Widget child; - int[] currentX = null; - int returnX = x; - x += nw + 1; - y += nh; - Pen treeLinePen = Pen.PEN_GREY_1px; - if (isCursor) - treeLinePen = Pen.PEN_BLUE_1px; - else if (isAncestor) - treeLinePen = Pen.PEN_GREEN_1px; - boolean childOverflow = wtWidget.childCount() > 8, - nothingRendered = true; - int bf = 0, af = -1; - for (int i=0; i 0 || af > 0){ - canvas.text(Pen.PEN_WHITE_TEXT_6px, currentX[1] + 1, y + 3, 0, "" + bf); - canvas.text(Pen.PEN_WHITE_TEXT_6px, currentX[1] + 1, y + 9, 0, "" + af); - } - int maxf = Math.max(bf, af); - return new int[]{x + (childOverflow ? (int)(6*Math.log10(maxf)) : 0), returnX + nw - 1}; - } - - // ############################### - // Rendering offset calculations - // ############################### - - private static double[] calculateOffset(Canvas canvas, Shape shape){ - return new double[]{ - canvas.x() + canvas.width() - (shape.x() + shape.width()), - canvas.y() + canvas.height() - (shape.y() + shape.height()) - }; - } - - private static Shape calculateInnerShape(Shape shape, double[] offset){ - if (offset[0] > 0 && offset[1] > 0) - return shape; - else{ - double offsetX = offset[0] > 0 ? 0 : offset[0]; - double offsetY = offset[1] > 0 ? 0 : offset[1]; - return Rect.from(shape.x() + offsetX, shape.y() + offsetY, - shape.width(), shape.height()); - } - } - - public static Shape repositionShape(Canvas canvas, Shape shape){ - double[] offset = calculateOffset(canvas,shape); // x,y - return calculateInnerShape(shape,offset); - } - - // fix WidgetInfo panel outside screen in some cases - public static Shape calculateWidgetInfoShape(Canvas canvas, Shape cwShape, double widgetInfoW, double widgetInfoH){ - Shape s = Rect.from(cwShape.x(), cwShape.y(), widgetInfoW, widgetInfoH); - Shape rs = repositionShape(canvas,s); - - // If y-axis canvas is over the screen (negative value), set to 0.0 - if(s.y() < 0.0) {s = Rect.from(cwShape.x(), 0.0, widgetInfoW, widgetInfoH);} - if(rs.y() < 0.0) {rs = Rect.from(rs.x(), 0.0, rs.width(), rs.height());} - - if (s == rs) - return cwShape; - else - return rs; - } - - // ##################### - // Screenshots helpers - // ##################### - - public static String getStateshot(State state){ - return ScreenshotSerialiser.saveStateshot(state.get(Tags.ConcreteID, "NoConcreteIdAvailable"), getStateshotBinary(state)); - } - - /** - * Method returns a binary representation of a state's screenshot. - * @param state - * @return - */ - public static AWTCanvas getStateshotBinary(State state) { - Shape viewPort = null; - if (state.childCount() > 0){ - viewPort = state.child(0).get(Tags.Shape, null); - if (viewPort != null && (viewPort.width() * viewPort.height() < 1)) - viewPort = null; - } - - //If the state Shape is not properly obtained, or the State has an error, use full monitor screen - List verdicts = state.get(Tags.OracleVerdicts, Collections.singletonList(Verdict.OK)); - if (viewPort == null || !Verdict.helperAreAllVerdictsOK(verdicts)) - viewPort = state.get(Tags.Shape, null); // get the SUT process canvas (usually, full monitor screen) - - // Validate viewport dimensions before taking the screenshot - if (viewPort == null || viewPort.width() <= 0 || viewPort.height() <= 0) { - // If viewport is still null, get a screenshot of all the screen - Rectangle screenRect = new Rectangle(Toolkit.getDefaultToolkit().getScreenSize()); - return AWTCanvas.fromScreenshot( - Rect.from(screenRect.x, screenRect.y, screenRect.width, screenRect.height), - getRootWindowHandle(state), - AWTCanvas.StorageFormat.PNG, - 1 - ); - } else { - // Capture and return the viewport screenshot - return AWTCanvas.fromScreenshot( - Rect.from(viewPort.x(), viewPort.y(), viewPort.width(), viewPort.height()), - getRootWindowHandle(state), - AWTCanvas.StorageFormat.PNG, - 1 - ); - } - } - - public static String getActionshot(State state, Action action){ - List targets = action.get(Tags.Targets, null); - if (targets != null){ - Widget w; - Shape s; - Rectangle r; - Rectangle actionArea = new Rectangle(Integer.MAX_VALUE,Integer.MAX_VALUE,Integer.MIN_VALUE,Integer.MIN_VALUE); - - for (Finder f : targets){ - w = f.apply(state); - s = w.get(Tags.Shape, null); - if(s == null) continue; - - r = new Rectangle((int)s.x(), (int)s.y(), (int)s.width(), (int)s.height()); - actionArea = actionArea.union(r); - } - - if (actionArea.isEmpty()) return null; - - AWTCanvas scrshot = AWTCanvas.fromScreenshot( - Rect.from(actionArea.x, actionArea.y, actionArea.width, actionArea.height), - getRootWindowHandle(state), - AWTCanvas.StorageFormat.PNG, - 1 - ); - - return ScreenshotSerialiser.saveActionshot( - state.get(Tags.ConcreteID, "NoConcreteIdAvailable"), - action.get(Tags.ConcreteID, "NoConcreteIdAvailable"), - scrshot - ); - } - return null; - } - - private static long getRootWindowHandle(State state) { - long windowHandle = 0; - if (state.childCount() > 0) { - windowHandle = state.child(0).get(Tags.HWND, 0L); - } - return windowHandle; - } - - - /** - * Calculate the max and the min ZIndex of all the widgets in a state - * @param state - */ - public static State calculateZIndices(State state) { - double minZIndex = Double.MAX_VALUE, - maxZIndex = Double.MIN_VALUE, - zindex; - for (Widget w : state){ - zindex = w.get(Tags.ZIndex).doubleValue(); - if (zindex < minZIndex) - minZIndex = zindex; - if (zindex > maxZIndex) - maxZIndex = zindex; - } - state.set(Tags.MinZIndex, minZIndex); - state.set(Tags.MaxZIndex, maxZIndex); - return state; - } - -} diff --git a/core/src/org/testar/monkey/Proc.java b/core/src/org/testar/monkey/Proc.java deleted file mode 100644 index 49abf689f..000000000 --- a/core/src/org/testar/monkey/Proc.java +++ /dev/null @@ -1,38 +0,0 @@ -/*************************************************************************************************** -* -* Copyright (c) 2013, 2014, 2015, 2016, 2017 Universitat Politecnica de Valencia - www.upv.es -* Copyright (c) 2017 Open Universiteit - www.ou.nl -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, -* this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the copyright holder nor the names of its -* contributors may be used to endorse or promote products derived from -* this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -* POSSIBILITY OF SUCH DAMAGE. -*******************************************************************************************************/ - -/** - * @author Sebastian Bauersfeld - */ -package org.testar.monkey; - -public interface Proc { - void run(); -} diff --git a/core/src/org/testar/monkey/UnFunc.java b/core/src/org/testar/monkey/UnFunc.java deleted file mode 100644 index 06fd66e82..000000000 --- a/core/src/org/testar/monkey/UnFunc.java +++ /dev/null @@ -1,38 +0,0 @@ -/*************************************************************************************************** -* -* Copyright (c) 2013, 2014, 2015, 2016, 2017 Universitat Politecnica de Valencia - www.upv.es -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, -* this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the copyright holder nor the names of its -* contributors may be used to endorse or promote products derived from -* this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -* POSSIBILITY OF SUCH DAMAGE. -*******************************************************************************************************/ - - -/** - * @author Sebastian Bauersfeld - */ -package org.testar.monkey; - -public interface UnFunc { - T apply(A argument); -} diff --git a/core/src/org/testar/monkey/UnProc.java b/core/src/org/testar/monkey/UnProc.java deleted file mode 100644 index daa4c4abc..000000000 --- a/core/src/org/testar/monkey/UnProc.java +++ /dev/null @@ -1,38 +0,0 @@ -/*************************************************************************************************** -* -* Copyright (c) 2013, 2014, 2015, 2016, 2017 Universitat Politecnica de Valencia - www.upv.es -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, -* this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the copyright holder nor the names of its -* contributors may be used to endorse or promote products derived from -* this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -* POSSIBILITY OF SUCH DAMAGE. -*******************************************************************************************************/ - - -/** - * @author Sebastian Bauersfeld - */ -package org.testar.monkey; - -public interface UnProc { - void run(A argument); -} diff --git a/core/src/org/testar/monkey/alayer/BFNavigator.java b/core/src/org/testar/monkey/alayer/BFNavigator.java index 38743bc17..010a80929 100644 --- a/core/src/org/testar/monkey/alayer/BFNavigator.java +++ b/core/src/org/testar/monkey/alayer/BFNavigator.java @@ -1,6 +1,7 @@ /*************************************************************************************************** * -* Copyright (c) 2013, 2014, 2015, 2016, 2017 Universitat Politecnica de Valencia - www.upv.es +* Copyright (c) 2013 - 2026 Universitat Politecnica de Valencia - www.upv.es +* Copyright (c) 2018 - 2026 Open Universiteit - www.ou.nl * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -27,15 +28,13 @@ * POSSIBILITY OF SUCH DAMAGE. *******************************************************************************************************/ -/** - * @author Sebastian Bauersfeld - */ package org.testar.monkey.alayer; import java.util.LinkedList; public class BFNavigator implements Navigator { - public void run(LinkedList buffer) { + @Override + public void accept(LinkedList buffer) { Widget w = buffer.getFirst(); for(int i = 0; i < w.childCount(); i++) buffer.add(w.child(i)); diff --git a/core/src/org/testar/monkey/alayer/DFNavigator.java b/core/src/org/testar/monkey/alayer/DFNavigator.java index 53caf2b3d..9fbaaddf1 100644 --- a/core/src/org/testar/monkey/alayer/DFNavigator.java +++ b/core/src/org/testar/monkey/alayer/DFNavigator.java @@ -1,6 +1,7 @@ /*************************************************************************************************** * -* Copyright (c) 2013, 2014, 2015, 2016, 2017 Universitat Politecnica de Valencia - www.upv.es +* Copyright (c) 2013 - 2026 Universitat Politecnica de Valencia - www.upv.es +* Copyright (c) 2018 - 2026 Open Universiteit - www.ou.nl * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -27,17 +28,13 @@ * POSSIBILITY OF SUCH DAMAGE. *******************************************************************************************************/ - - -/** - * @author Sebastian Bauersfeld - */ package org.testar.monkey.alayer; import java.util.LinkedList; public class DFNavigator implements Navigator { - public void run(LinkedList buffer) { + @Override + public void accept(LinkedList buffer) { Widget f = buffer.getFirst(); for(int i = f.childCount() - 1; i >= 0; i--) buffer.add(1, f.child(i)); diff --git a/core/src/org/testar/monkey/alayer/Navigator.java b/core/src/org/testar/monkey/alayer/Navigator.java index 7795be7a3..38f056695 100644 --- a/core/src/org/testar/monkey/alayer/Navigator.java +++ b/core/src/org/testar/monkey/alayer/Navigator.java @@ -1,6 +1,7 @@ /*************************************************************************************************** * -* Copyright (c) 2013, 2014, 2015, 2016, 2017 Universitat Politecnica de Valencia - www.upv.es +* Copyright (c) 2013 - 2026 Universitat Politecnica de Valencia - www.upv.es +* Copyright (c) 2018 - 2026 Open Universiteit - www.ou.nl * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -27,16 +28,12 @@ * POSSIBILITY OF SUCH DAMAGE. *******************************************************************************************************/ - -/** - * @author Sebastian Bauersfeld - */ package org.testar.monkey.alayer; import java.util.LinkedList; +import java.util.function.Consumer; -import org.testar.monkey.UnProc; - -public interface Navigator extends UnProc> { - void run(LinkedList buffer); +public interface Navigator extends Consumer> { + @Override + void accept(LinkedList buffer); } diff --git a/core/src/org/testar/monkey/alayer/SplineTrajectory.java b/core/src/org/testar/monkey/alayer/SplineTrajectory.java index 3f76e40b1..85c560ef0 100644 --- a/core/src/org/testar/monkey/alayer/SplineTrajectory.java +++ b/core/src/org/testar/monkey/alayer/SplineTrajectory.java @@ -1,6 +1,7 @@ /*************************************************************************************************** * -* Copyright (c) 2013, 2014, 2015, 2016, 2017 Universitat Politecnica de Valencia - www.upv.es +* Copyright (c) 2013 - 2026 Universitat Politecnica de Valencia - www.upv.es +* Copyright (c) 2018 - 2026 Open Universiteit - www.ou.nl * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -27,20 +28,16 @@ * POSSIBILITY OF SUCH DAMAGE. *******************************************************************************************************/ - -/** - * @author Sebastian Bauersfeld - */ package org.testar.monkey.alayer; import java.io.Serializable; import java.util.Iterator; import java.util.List; +import java.util.function.Function; import org.testar.monkey.Assert; -import org.testar.monkey.UnFunc; -public final class SplineTrajectory implements UnFunc>, Serializable { +public final class SplineTrajectory implements Function>, Serializable { private static final long serialVersionUID = -7833747078043023184L; final Position[] positions; diff --git a/core/src/org/testar/monkey/alayer/Tags.java b/core/src/org/testar/monkey/alayer/Tags.java index 07b7837c5..aafdfb849 100644 --- a/core/src/org/testar/monkey/alayer/Tags.java +++ b/core/src/org/testar/monkey/alayer/Tags.java @@ -32,8 +32,6 @@ import org.testar.CodingManager; import org.testar.monkey.Pair; -import org.testar.monkey.Proc; -import org.testar.monkey.UnFunc; import org.testar.monkey.alayer.devices.Keyboard; import org.testar.monkey.alayer.devices.Mouse; import org.testar.monkey.alayer.devices.ProcessHandle; @@ -59,11 +57,6 @@ private Tags() {} * by other widgets (use the HitTester Tag instead!) */ public static final Tag Shape = from("Shape", Shape.class); - /** Usually attached to widgets. It tells whether this widget this widget is rendered. - * If so, it does not necessarily mean that it is also visible, since it could still - * be obfuscated by other controls. */ - public static final Tag Rendered = from("Rendered", Boolean.class); - /** A short human-readable descriptive text for a widget / action / or system */ public static final Tag Desc = from("Desc", String.class); @@ -109,10 +102,7 @@ private Tags() {} /** Usually attached to window widgets. Determines whether the widget is modal (blocks other widgets) */ public static final Tag Modal = from("Modal", Boolean.class); - - /** Usually attached to sliders or scrollbars. Determines the orientation (horizontal, vertical or an arbitrary angle) */ - public static final Tag Angle = from("Angle", Double.class); - + /** The text of a widget (e.g. the text within a text box) */ public static final Tag Text = from("Text", String.class); @@ -125,9 +115,6 @@ private Tags() {} public static final Tag Abstract_R_ID = from(CodingManager.ABSTRACT_R_ID, String.class); public static final Tag Abstract_R_T_ID = from(CodingManager.ABSTRACT_R_T_ID, String.class); public static final Tag Abstract_R_T_P_ID = from(CodingManager.ABSTRACT_R_T_P_ID, String.class); - - @SuppressWarnings("unchecked") - public static final Tag> DynDesc = from("DynDesc", (Class>)(Class)UnFunc.class); /** A visualizer, which visualizes a widget or an action, so that one can get an idea of what the action will do when executed */ public static final Tag Visualizer = from("Visualizer", Visualizer.class); @@ -183,7 +170,6 @@ private Tags() {} public static final Tag ExecutedAction = from("ExecutedAction", Action.class); public static final Tag ActionDuration = from("ActionDuration", Double.class); public static final Tag ActionDelay = from("ActionDelay", Double.class); - public static final Tag UsedResources = from("Resources", String.class); public static final Tag Representation = from("Representation",String.class); /** A list of process handles. Usually attached to a system. Process handles allow to obtain information about and stop the processes that they refer to. */ @@ -197,7 +183,7 @@ private Tags() {} /** Usually attached to systems. A system activator can bring a system to the foreground. E.g.: If another process is currently in the foreground, * the SystemActivator makes sure that the SUT gets focused again. */ @SuppressWarnings("unchecked") - public static final Tag SystemActivator = from("SystemActivator", (Class)(Class)Proc.class); + public static final Tag SystemActivator = from("SystemActivator", (Class)(Class)Runnable.class); /** * The original widget that can be attached to things like actions diff --git a/core/src/org/testar/monkey/alayer/WidgetIterator.java b/core/src/org/testar/monkey/alayer/WidgetIterator.java index 6ac796863..ddb6bbd82 100644 --- a/core/src/org/testar/monkey/alayer/WidgetIterator.java +++ b/core/src/org/testar/monkey/alayer/WidgetIterator.java @@ -1,6 +1,7 @@ /*************************************************************************************************** * -* Copyright (c) 2013, 2014, 2015, 2016, 2017 Universitat Politecnica de Valencia - www.upv.es +* Copyright (c) 2013 - 2026 Universitat Politecnica de Valencia - www.upv.es +* Copyright (c) 2018 - 2026 Open Universiteit - www.ou.nl * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -27,10 +28,6 @@ * POSSIBILITY OF SUCH DAMAGE. *******************************************************************************************************/ - -/** - * @author Sebastian Bauersfeld - */ package org.testar.monkey.alayer; import java.util.Iterator; @@ -52,7 +49,7 @@ public WidgetIterator(Widget start, Navigator navi){ this.buffer = new LinkedList(); this.navi = navi; this.buffer.add(start); - this.navi.run(this.buffer); + this.navi.accept(this.buffer); } public boolean hasNext() { return !buffer.isEmpty(); } @@ -60,7 +57,7 @@ public WidgetIterator(Widget start, Navigator navi){ public Widget next() { Widget ret = buffer.remove(); if(!buffer.isEmpty()) - navi.run(buffer); + navi.accept(buffer); return ret; } diff --git a/core/src/org/testar/monkey/alayer/actions/ActivateSystem.java b/core/src/org/testar/monkey/alayer/actions/ActivateSystem.java index ca7dc5fbc..7532012d1 100644 --- a/core/src/org/testar/monkey/alayer/actions/ActivateSystem.java +++ b/core/src/org/testar/monkey/alayer/actions/ActivateSystem.java @@ -1,6 +1,7 @@ /*************************************************************************************************** * -* Copyright (c) 2013, 2014, 2015, 2016, 2017 Universitat Politecnica de Valencia - www.upv.es +* Copyright (c) 2013 - 2026 Universitat Politecnica de Valencia - www.upv.es +* Copyright (c) 2018 - 2026 Open Universiteit - www.ou.nl * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -27,14 +28,9 @@ * POSSIBILITY OF SUCH DAMAGE. *******************************************************************************************************/ - -/** - * @author Sebastian Bauersfeld - */ package org.testar.monkey.alayer.actions; import org.testar.monkey.Assert; -import org.testar.monkey.Proc; import org.testar.monkey.Util; import org.testar.monkey.alayer.Action; import org.testar.monkey.alayer.Role; @@ -54,7 +50,7 @@ public void run(SUT system, State state, double duration) throws ActionFailedExc try{ double start = Util.time(); - Proc activator = system.get(Tags.SystemActivator); + Runnable activator = system.get(Tags.SystemActivator); activator.run(); Util.pause(duration - (Util.time() - start)); }catch(NoSuchTagException nste){ @@ -64,13 +60,11 @@ public void run(SUT system, State state, double duration) throws ActionFailedExc public String toString(){ return "Bring the system to the foreground."; } - // by urueda @Override public String toString(Role... discardParameters) { return toString(); } - - // by urueda + @Override public String toShortString() { Role r = get(Tags.Role, null); @@ -80,7 +74,6 @@ public String toShortString() { return toString(); } - // by urueda @Override public String toParametersString() { return ""; diff --git a/core/src/org/testar/monkey/alayer/visualizers/TrajectoryVisualizer.java b/core/src/org/testar/monkey/alayer/visualizers/TrajectoryVisualizer.java index a51492eea..fe65e3ce3 100644 --- a/core/src/org/testar/monkey/alayer/visualizers/TrajectoryVisualizer.java +++ b/core/src/org/testar/monkey/alayer/visualizers/TrajectoryVisualizer.java @@ -1,7 +1,7 @@ /*************************************************************************************************** * -* Copyright (c) 2013 - 2025 Universitat Politecnica de Valencia - www.upv.es -* Copyright (c) 2018 - 2025 Open Universiteit - www.ou.nl +* Copyright (c) 2013 - 2026 Universitat Politecnica de Valencia - www.upv.es +* Copyright (c) 2018 - 2026 Open Universiteit - www.ou.nl * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -31,9 +31,9 @@ package org.testar.monkey.alayer.visualizers; import java.util.Iterator; +import java.util.function.Function; import org.testar.monkey.Assert; -import org.testar.monkey.UnFunc; import org.testar.monkey.Util; import org.testar.monkey.alayer.Canvas; import org.testar.monkey.alayer.Pen; @@ -47,14 +47,14 @@ public class TrajectoryVisualizer implements Visualizer { private static final long serialVersionUID = 1107281202398264314L; - final UnFunc> trajectory; + final Function> trajectory; final Pen pen; public TrajectoryVisualizer(Pen pen, Position... positions){ this(new SplineTrajectory(10, positions), pen); } - public TrajectoryVisualizer(UnFunc> trajectory, Pen pen){ + public TrajectoryVisualizer(Function> trajectory, Pen pen){ Assert.notNull(trajectory, pen); Assert.isTrue(pen.strokeWidth() != null); this.trajectory = trajectory; diff --git a/core/src/org/testar/screenshot/ScreenshotProvider.java b/core/src/org/testar/screenshot/ScreenshotProvider.java new file mode 100644 index 000000000..a4ded1850 --- /dev/null +++ b/core/src/org/testar/screenshot/ScreenshotProvider.java @@ -0,0 +1,43 @@ +/*************************************************************************************************** + * + * Copyright (c) 2026 Open Universiteit - www.ou.nl + * Copyright (c) 2026 Universitat Politecnica de Valencia - www.upv.es + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *******************************************************************************************************/ + +package org.testar.screenshot; + +import org.testar.monkey.alayer.AWTCanvas; +import org.testar.monkey.alayer.Action; +import org.testar.monkey.alayer.State; + +public interface ScreenshotProvider { + + AWTCanvas getStateshotBinary(State state); + + String getActionshot(State state, Action action); + +} diff --git a/core/src/org/testar/stub/StateStub.java b/core/src/org/testar/stub/StateStub.java index f31db9837..a9be970a5 100644 --- a/core/src/org/testar/stub/StateStub.java +++ b/core/src/org/testar/stub/StateStub.java @@ -1,7 +1,7 @@ /*************************************************************************************************** * - * Copyright (c) 2020 - 2023 Open Universiteit - www.ou.nl - * Copyright (c) 2020 - 2023 Universitat Politecnica de Valencia - www.upv.es + * Copyright (c) 2020 - 2026 Open Universiteit - www.ou.nl + * Copyright (c) 2020 - 2026 Universitat Politecnica de Valencia - www.upv.es * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -39,6 +39,14 @@ public class StateStub extends WidgetStub implements State { private static final long serialVersionUID = -2972642849689796355L; + public StateStub() { + setRoot(this); + } + + public void setRoot(State root) { + super.setRoot(root); + } + @Override public Iterator iterator() { return new WidgetIterator(this); diff --git a/core/src/org/testar/stub/WidgetStub.java b/core/src/org/testar/stub/WidgetStub.java index 27c80e0a7..bb366e412 100644 --- a/core/src/org/testar/stub/WidgetStub.java +++ b/core/src/org/testar/stub/WidgetStub.java @@ -1,7 +1,7 @@ /*************************************************************************************************** * - * Copyright (c) 2020 - 2023 Open Universiteit - www.ou.nl - * Copyright (c) 2020 - 2023 Universitat Politecnica de Valencia - www.upv.es + * Copyright (c) 2020 - 2026 Open Universiteit - www.ou.nl + * Copyright (c) 2020 - 2026 Universitat Politecnica de Valencia - www.upv.es * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -55,10 +55,24 @@ public class WidgetStub extends TaggableBase implements Widget { private final List widgets = new ArrayList<>(); private Widget parent = null; + private State root = null; @Override public State root() { - return (State)this; + if (root != null) { + return root; + } + if (parent != null) { + return parent.root(); + } + if (this instanceof State) { + return (State) this; + } + return null; + } + + public void setRoot(State root) { + this.root = root; } @Override diff --git a/core/src/org/testar/util/IndexUtil.java b/core/src/org/testar/util/IndexUtil.java new file mode 100644 index 000000000..f8e45ebdc --- /dev/null +++ b/core/src/org/testar/util/IndexUtil.java @@ -0,0 +1,65 @@ +/*************************************************************************************************** + * + * Copyright (c) 2016 - 2026 Universitat Politecnica de Valencia - www.upv.es + * Copyright (c) 2019 - 2026 Open Universiteit - www.ou.nl + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *******************************************************************************************************/ + +package org.testar.util; + +import java.util.Objects; + +import org.testar.monkey.alayer.State; +import org.testar.monkey.alayer.Tags; +import org.testar.monkey.alayer.Widget; + +public class IndexUtil { + + private IndexUtil() { + } + + /** + * Calculate the max and the min ZIndex of all the widgets in a state + * + * @param state + */ + public static State calculateZIndices(State state) { + Objects.requireNonNull(state, "State cannot be null"); + double minZIndex = Double.MAX_VALUE; + double maxZIndex = Double.MIN_VALUE; + for (Widget w : state) { + double zindex = w.get(Tags.ZIndex, 0.0).doubleValue(); + if (zindex < minZIndex) + minZIndex = zindex; + if (zindex > maxZIndex) + maxZIndex = zindex; + } + state.set(Tags.MinZIndex, minZIndex); + state.set(Tags.MaxZIndex, maxZIndex); + return state; + } + +} diff --git a/core/src/org/testar/util/ScreenshotUtil.java b/core/src/org/testar/util/ScreenshotUtil.java new file mode 100644 index 000000000..2dfe72a2f --- /dev/null +++ b/core/src/org/testar/util/ScreenshotUtil.java @@ -0,0 +1,138 @@ +/*************************************************************************************************** + * + * Copyright (c) 2016 - 2026 Universitat Politecnica de Valencia - www.upv.es + * Copyright (c) 2019 - 2026 Open Universiteit - www.ou.nl + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *******************************************************************************************************/ + +package org.testar.util; + +import java.awt.Rectangle; +import java.awt.Toolkit; +import java.util.Collections; +import java.util.List; +import java.util.Objects; + +import org.testar.monkey.alayer.AWTCanvas; +import org.testar.monkey.alayer.Action; +import org.testar.monkey.alayer.Finder; +import org.testar.monkey.alayer.Rect; +import org.testar.monkey.alayer.Shape; +import org.testar.monkey.alayer.State; +import org.testar.monkey.alayer.Tags; +import org.testar.monkey.alayer.Verdict; +import org.testar.monkey.alayer.Widget; +import org.testar.serialisation.ScreenshotSerialiser; + +public class ScreenshotUtil { + + private ScreenshotUtil() { + } + + /** + * Method returns a binary representation of a state's screenshot. + * + * @param state + * @return + */ + public static AWTCanvas getStateshotBinary(State state) { + Objects.requireNonNull(state, "State cannot be null"); + Shape viewPort = null; + if (state.childCount() > 0) { + viewPort = state.child(0).get(Tags.Shape, null); + if (viewPort != null && (viewPort.width() * viewPort.height() < 1)) + viewPort = null; + } + + // If the state Shape is not properly obtained, or the State has an error, use + // full monitor screen + List verdicts = state.get(Tags.OracleVerdicts, Collections.singletonList(Verdict.OK)); + if (viewPort == null || !Verdict.helperAreAllVerdictsOK(verdicts)) + viewPort = state.get(Tags.Shape, null); // get the SUT process canvas (usually, full monitor screen) + + // Validate viewport dimensions before taking the screenshot + if (viewPort == null || viewPort.width() <= 0 || viewPort.height() <= 0) { + // If viewport is still null, get a screenshot of all the screen + Rectangle screenRect = new Rectangle(Toolkit.getDefaultToolkit().getScreenSize()); + return AWTCanvas.fromScreenshot( + Rect.from(screenRect.x, screenRect.y, screenRect.width, screenRect.height), + getRootWindowHandle(state), + AWTCanvas.StorageFormat.PNG, + 1); + } else { + // Capture and return the viewport screenshot + return AWTCanvas.fromScreenshot( + Rect.from(viewPort.x(), viewPort.y(), viewPort.width(), viewPort.height()), + getRootWindowHandle(state), + AWTCanvas.StorageFormat.PNG, + 1); + } + } + + public static String getActionshot(State state, Action action) { + Objects.requireNonNull(state, "State cannot be null"); + Objects.requireNonNull(action, "Action cannot be null"); + List targets = action.get(Tags.Targets, null); + if (targets != null) { + Rectangle actionArea = new Rectangle(Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MIN_VALUE, Integer.MIN_VALUE); + + for (Finder f : targets) { + Widget w = f.apply(state); + Shape s = w.get(Tags.Shape, null); + if (s == null) + continue; + + Rectangle r = new Rectangle((int) s.x(), (int) s.y(), (int) s.width(), (int) s.height()); + actionArea = actionArea.union(r); + } + + if (actionArea.isEmpty()) + return ""; + + AWTCanvas scrshot = AWTCanvas.fromScreenshot( + Rect.from(actionArea.x, actionArea.y, actionArea.width, actionArea.height), + getRootWindowHandle(state), + AWTCanvas.StorageFormat.PNG, + 1); + + return ScreenshotSerialiser.saveActionshot( + state.get(Tags.ConcreteID, "NoConcreteIdAvailable"), + action.get(Tags.ConcreteID, "NoConcreteIdAvailable"), + scrshot); + } + return ""; + } + + private static long getRootWindowHandle(State state) { + Objects.requireNonNull(state, "State cannot be null"); + long windowHandle = 0; + if (state.childCount() > 0) { + windowHandle = state.child(0).get(Tags.HWND, 0L); + } + return windowHandle; + } + +} diff --git a/core/src/org/testar/util/VisualizationUtil.java b/core/src/org/testar/util/VisualizationUtil.java new file mode 100644 index 000000000..2168107b7 --- /dev/null +++ b/core/src/org/testar/util/VisualizationUtil.java @@ -0,0 +1,100 @@ +/*************************************************************************************************** + * + * Copyright (c) 2016 - 2026 Universitat Politecnica de Valencia - www.upv.es + * Copyright (c) 2019 - 2026 Open Universiteit - www.ou.nl + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *******************************************************************************************************/ + +package org.testar.util; + +import java.util.Objects; + +import org.testar.monkey.alayer.Canvas; +import org.testar.monkey.alayer.Rect; +import org.testar.monkey.alayer.Shape; + +public class VisualizationUtil { + + private VisualizationUtil() { + } + + // Build the info-panel shape near the current widget and keep it inside the visible canvas. + public static Shape calculateWidgetInfoShape(Canvas canvas, Shape cwShape, double widgetInfoW, double widgetInfoH) { + Objects.requireNonNull(canvas, "Canvas cannot be null"); + Objects.requireNonNull(cwShape, "Current widget shape cannot be null"); + if (widgetInfoW <= 0.0 || widgetInfoH <= 0.0) { + return cwShape; + } + + Shape s = Rect.from(cwShape.x(), cwShape.y(), widgetInfoW, widgetInfoH); + Shape rs = repositionShape(canvas, s); + + // If y-axis canvas is over the screen (negative value), set to 0.0 + if (s.y() < 0.0) { + s = Rect.from(cwShape.x(), 0.0, widgetInfoW, widgetInfoH); + } + if (rs.y() < 0.0) { + rs = Rect.from(rs.x(), 0.0, rs.width(), rs.height()); + } + + // If no repositioning was needed, keep the original widget shape. + if (s == rs) + return cwShape; + else + return rs; + } + + // Reposition a shape only when it overflows the canvas bounds. + public static Shape repositionShape(Canvas canvas, Shape shape) { + Objects.requireNonNull(canvas, "Canvas cannot be null"); + Objects.requireNonNull(shape, "Shape cannot be null"); + double[] offset = calculateOffset(canvas, shape); + return calculateInnerShape(shape, offset); + } + + // Positive offset means the shape still fits on that axis; negative means overflow amount. + private static double[] calculateOffset(Canvas canvas, Shape shape) { + return new double[] { + canvas.x() + canvas.width() - (shape.x() + shape.width()), + canvas.y() + canvas.height() - (shape.y() + shape.height()) + }; + } + + // Shift the shape back by the overflow amount while preserving size. + private static Shape calculateInnerShape(Shape shape, double[] offset) { + if (offset[0] > 0 && offset[1] > 0) + return shape; + else { + double offsetX = offset[0] > 0 ? 0 : offset[0]; + double offsetY = offset[1] > 0 ? 0 : offset[1]; + return Rect.from(shape.x() + offsetX, + shape.y() + offsetY, + shape.width(), + shape.height()); + } + } + +} diff --git a/core/test/org/testar/util/IndexUtilTest.java b/core/test/org/testar/util/IndexUtilTest.java new file mode 100644 index 000000000..8cb887867 --- /dev/null +++ b/core/test/org/testar/util/IndexUtilTest.java @@ -0,0 +1,75 @@ +package org.testar.util; + +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertEquals; + +import org.junit.Test; +import org.testar.monkey.alayer.Tags; +import org.testar.stub.StateStub; +import org.testar.stub.WidgetStub; + +public class IndexUtilTest { + + @Test + public void calculateZIndices_SingleWidget() { + StateStub state = new StateStub(); + WidgetStub w1 = new WidgetStub(); + + state.addChild(w1); + w1.setParent(state); + + state.set(Tags.ZIndex, 3.0); + w1.set(Tags.ZIndex, 3.0); + + IndexUtil.calculateZIndices(state); + + assertEquals(3.0, state.get(Tags.MinZIndex), 0.0); + assertEquals(3.0, state.get(Tags.MaxZIndex), 0.0); + } + + @Test + public void calculateZIndices_MultipleWidgets() { + StateStub state = new StateStub(); + WidgetStub w1 = new WidgetStub(); + WidgetStub w2 = new WidgetStub(); + WidgetStub w3 = new WidgetStub(); + + state.addChild(w1); + state.addChild(w2); + state.addChild(w3); + w1.setParent(state); + w2.setParent(state); + w3.setParent(state); + + state.set(Tags.ZIndex, 4.0); + w1.set(Tags.ZIndex, 5.0); + w2.set(Tags.ZIndex, -1.0); + w3.set(Tags.ZIndex, 2.0); + + StateStub result = (StateStub) IndexUtil.calculateZIndices(state); + + assertSame(state, result); + assertEquals(-1.0, state.get(Tags.MinZIndex), 0.0); + assertEquals(5.0, state.get(Tags.MaxZIndex), 0.0); + } + + @Test + public void calculateZIndices_WidgetHasNoZIndexTag() { + StateStub state = new StateStub(); + WidgetStub w1 = new WidgetStub(); + + state.addChild(w1); + w1.setParent(state); + // Keep state ZIndex unset on purpose. + w1.set(Tags.ZIndex, 1.0); + + IndexUtil.calculateZIndices(state); + assertEquals(0.0, state.get(Tags.MinZIndex), 0.0); + assertEquals(1.0, state.get(Tags.MaxZIndex), 0.0); + } + + @Test(expected = NullPointerException.class) + public void calculateZIndices_NullState() { + IndexUtil.calculateZIndices(null); + } +} diff --git a/core/test/org/testar/util/ScreenshotUtilTest.java b/core/test/org/testar/util/ScreenshotUtilTest.java new file mode 100644 index 000000000..3ec21e373 --- /dev/null +++ b/core/test/org/testar/util/ScreenshotUtilTest.java @@ -0,0 +1,90 @@ +package org.testar.util; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.util.Collections; +import java.util.List; + +import org.junit.Test; +import org.testar.monkey.alayer.Action; +import org.testar.monkey.alayer.Finder; +import org.testar.monkey.alayer.Shape; +import org.testar.monkey.alayer.State; +import org.testar.monkey.alayer.Tags; +import org.testar.monkey.alayer.Widget; + +public class ScreenshotUtilTest { + + @Test + public void getStateshotBinary_NullStateThrows() { + try { + ScreenshotUtil.getStateshotBinary(null); + fail("Expected NullPointerException"); + } catch (NullPointerException expected) { + assertEquals("State cannot be null", expected.getMessage()); + } + } + + @Test + public void getActionshot_NullStateThrows() { + Action action = mock(Action.class); + try { + ScreenshotUtil.getActionshot(null, action); + fail("Expected NullPointerException"); + } catch (NullPointerException expected) { + assertEquals("State cannot be null", expected.getMessage()); + } + } + + @Test + public void getActionshot_NullActionThrows() { + State state = mock(State.class); + try { + ScreenshotUtil.getActionshot(state, null); + fail("Expected NullPointerException"); + } catch (NullPointerException expected) { + assertEquals("Action cannot be null", expected.getMessage()); + } + } + + @Test + public void getActionshot_NoTargetsReturnsEmptyString() { + State state = mock(State.class); + Action action = mock(Action.class); + when(action.get(Tags.Targets, null)).thenReturn(null); + + String result = ScreenshotUtil.getActionshot(state, action); + + assertEquals("", result); + } + + @Test + public void getActionshot_EmptyTargetsReturnsEmptyString() { + State state = mock(State.class); + Action action = mock(Action.class); + when(action.get(Tags.Targets, null)).thenReturn(Collections.emptyList()); + + String result = ScreenshotUtil.getActionshot(state, action); + + assertEquals("", result); + } + + @Test + public void getActionshot_TargetsWithNullShapesReturnsEmptyString() { + State state = mock(State.class); + Action action = mock(Action.class); + Finder finder = mock(Finder.class); + Widget widget = mock(Widget.class); + + when(action.get(Tags.Targets, null)).thenReturn(List.of(finder)); + when(finder.apply(state)).thenReturn(widget); + when(widget.get(Tags.Shape, null)).thenReturn((Shape) null); + + String result = ScreenshotUtil.getActionshot(state, action); + + assertEquals("", result); + } +} diff --git a/core/test/org/testar/util/VisualizationUtilTest.java b/core/test/org/testar/util/VisualizationUtilTest.java new file mode 100644 index 000000000..7bd6afd54 --- /dev/null +++ b/core/test/org/testar/util/VisualizationUtilTest.java @@ -0,0 +1,134 @@ +package org.testar.util; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertSame; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import org.junit.Test; +import org.testar.monkey.alayer.Canvas; +import org.testar.monkey.alayer.Rect; +import org.testar.monkey.alayer.Shape; + +public class VisualizationUtilTest { + + @Test + public void repositionShape_InsideCanvas() { + Canvas canvas = mock(Canvas.class); + Shape shape = Rect.from(10, 10, 20, 20); + + when(canvas.x()).thenReturn(0.0); + when(canvas.y()).thenReturn(0.0); + when(canvas.width()).thenReturn(200.0); + when(canvas.height()).thenReturn(200.0); + + Shape result = VisualizationUtil.repositionShape(canvas, shape); + + assertSame(shape, result); + } + + @Test + public void repositionShape_OverflowingCanvas() { + Canvas canvas = mock(Canvas.class); + Shape shape = Rect.from(90, 80, 20, 30); + + when(canvas.x()).thenReturn(0.0); + when(canvas.y()).thenReturn(0.0); + when(canvas.width()).thenReturn(100.0); + when(canvas.height()).thenReturn(100.0); + + Shape result = VisualizationUtil.repositionShape(canvas, shape); + + assertEquals(80.0, result.x(), 0.0); + assertEquals(70.0, result.y(), 0.0); + assertEquals(20.0, result.width(), 0.0); + assertEquals(30.0, result.height(), 0.0); + } + + @Test + public void calculateWidgetInfoShape_NoRepositionNeeded() { + Canvas canvas = mock(Canvas.class); + Shape currentWidgetShape = Rect.from(50, 50, 20, 20); + + when(canvas.x()).thenReturn(0.0); + when(canvas.y()).thenReturn(0.0); + when(canvas.width()).thenReturn(500.0); + when(canvas.height()).thenReturn(500.0); + + Shape result = VisualizationUtil.calculateWidgetInfoShape(canvas, currentWidgetShape, 100.0, 60.0); + + assertSame(currentWidgetShape, result); + } + + @Test + public void calculateWidgetInfoShape_NegativeYToZero() { + Canvas canvas = mock(Canvas.class); + Shape currentWidgetShape = Rect.from(50, -5, 20, 20); + + when(canvas.x()).thenReturn(0.0); + when(canvas.y()).thenReturn(0.0); + when(canvas.width()).thenReturn(200.0); + when(canvas.height()).thenReturn(200.0); + + Shape result = VisualizationUtil.calculateWidgetInfoShape(canvas, currentWidgetShape, 40.0, 20.0); + + assertEquals(0.0, result.y(), 0.0); + } + + @Test + public void repositionShape_NullCanvas() { + Shape shape = Rect.from(10, 10, 20, 20); + try { + VisualizationUtil.repositionShape(null, shape); + } catch (NullPointerException expected) { + assertEquals("Canvas cannot be null", expected.getMessage()); + return; + } + throw new AssertionError("Expected NullPointerException"); + } + + @Test + public void repositionShape_NullShape() { + Canvas canvas = mock(Canvas.class); + try { + VisualizationUtil.repositionShape(canvas, null); + } catch (NullPointerException expected) { + assertEquals("Shape cannot be null", expected.getMessage()); + return; + } + throw new AssertionError("Expected NullPointerException"); + } + + @Test + public void calculateWidgetInfoShape_NullCanvas() { + Shape currentWidgetShape = Rect.from(50, 50, 20, 20); + try { + VisualizationUtil.calculateWidgetInfoShape(null, currentWidgetShape, 100.0, 60.0); + } catch (NullPointerException expected) { + assertEquals("Canvas cannot be null", expected.getMessage()); + return; + } + throw new AssertionError("Expected NullPointerException"); + } + + @Test + public void calculateWidgetInfoShape_NullCurrentShape() { + Canvas canvas = mock(Canvas.class); + try { + VisualizationUtil.calculateWidgetInfoShape(canvas, null, 100.0, 60.0); + } catch (NullPointerException expected) { + assertEquals("Current widget shape cannot be null", expected.getMessage()); + return; + } + throw new AssertionError("Expected NullPointerException"); + } + + @Test + public void calculateWidgetInfoShape_InvalidWidgetInfo() { + Canvas canvas = mock(Canvas.class); + Shape currentWidgetShape = Rect.from(50, 50, 20, 20); + Shape result = VisualizationUtil.calculateWidgetInfoShape(canvas, currentWidgetShape, 0.0, 60.0); + assertSame(currentWidgetShape, result); + } + +} diff --git a/ios/src/org/testar/monkey/alayer/ios/IOSAppiumFramework.java b/ios/src/org/testar/monkey/alayer/ios/IOSAppiumFramework.java index 3e22d3ec9..97d0a402a 100644 --- a/ios/src/org/testar/monkey/alayer/ios/IOSAppiumFramework.java +++ b/ios/src/org/testar/monkey/alayer/ios/IOSAppiumFramework.java @@ -1,7 +1,7 @@ /*************************************************************************************************** * - * Copyright (c) 2020 - 2024 Universitat Politecnica de Valencia - www.upv.es - * Copyright (c) 2020 - 2024 Open Universiteit - www.ou.nl + * Copyright (c) 2020 - 2026 Universitat Politecnica de Valencia - www.upv.es + * Copyright (c) 2020 - 2026 Open Universiteit - www.ou.nl * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -309,7 +309,7 @@ public static String getScreenshotAction(State state, Action action) throws IOEx } // Note that besides obtaining a screenshot of the SUT it also highlights which action was clicked! - public static AWTCanvas getScreenshotBinary(State state, Widget widget) throws IOException { + public static AWTCanvas getScreenshotBinary(State state) throws IOException { byte[] byteImage = driver.getScreenshotAs(OutputType.BYTES); InputStream is = new ByteArrayInputStream(byteImage); return AWTCanvas.fromInputStream(is); diff --git a/ios/src/org/testar/monkey/alayer/ios/IOSProtocolUtil.java b/ios/src/org/testar/monkey/alayer/ios/IOSProtocolUtil.java deleted file mode 100644 index fed073606..000000000 --- a/ios/src/org/testar/monkey/alayer/ios/IOSProtocolUtil.java +++ /dev/null @@ -1,152 +0,0 @@ -/*************************************************************************************************** - * - * Copyright (c) 2020 - 2024 Universitat Politecnica de Valencia - www.upv.es - * Copyright (c) 2020 - 2024 Open Universiteit - www.ou.nl - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holder nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *******************************************************************************************************/ - -package org.testar.monkey.alayer.ios; - -import org.testar.ProtocolUtil; -import org.testar.monkey.Pair; -import org.testar.monkey.alayer.*; -import org.testar.monkey.alayer.ios.enums.IOSTags; - -import java.io.IOException; -import java.util.ArrayList; - -public class IOSProtocolUtil extends ProtocolUtil { - - public static String getActionshot(State state, Action action) { - try { - return IOSAppiumFramework.getScreenshotAction(state, action); - } catch(Exception e) { - System.err.println("Exception when taking action screenshot: " + e); - } - - return ProtocolUtil.getActionshot(state, action); - } - - public static String getStateshot(State state) { - try { - return IOSAppiumFramework.getScreenshotState(state); - } catch(Exception e) { - System.err.println("Exception occured when trying to take a screenshot of the iOS emulator: " + e); - } - - return ProtocolUtil.getStateshot(state); - } - - public static String getStateshotSpyMode(State state) { - try { - return IOSAppiumFramework.getScreenshotSpyMode(state.get(Tags.ConcreteID, "NoConcreteIdAvailable")); - } catch(Exception e) { - System.err.println("Exception occured when trying to take a screenshot of the iOS emulator: " + e); - } - - return ProtocolUtil.getStateshot(state); - } - - /** - * Method returns a binary representation of a state's screenshot. - * @param state - * @return - */ - public static AWTCanvas getStateshotBinary(State state, Widget widget) { - // Obtain the binary screenshotfile through the appium driver. - try { - return IOSAppiumFramework.getScreenshotBinary(state, widget); - } catch (IOException e) { - System.err.println("Exception occured when trying to take a binary screenshot of the iOS emulator: " + e); - } - - return ProtocolUtil.getStateshotBinary(state); - } - - // Method which constructs the hierachy xpath (absolute path) - // This method is needed as this is the only way to uniquely identify an GUI object if it has no accessibilityID. - //TODO: THIS METHOD IS VERY INEFFICIENT! Seems to work correctly though. - public static String constructXpath(Widget w) { - StringBuilder sb = new StringBuilder(); - Widget parentWidget = w; - - while (parentWidget != w.root()) { - String classTag = parentWidget.get(Tags.Desc); - int indexNumber = parentWidget.get(IOSTags.iosNodeIndex); - - if (classTag.equals("Root")) { - break; - } - - parentWidget = parentWidget.parent(); - - ArrayList> childClasses = new ArrayList<>(); - - for (int i = 0; i < parentWidget.childCount(); i++) { - childClasses.add(new Pair(parentWidget.child(i).get(Tags.Desc), parentWidget.child(i).get(IOSTags.iosNodeIndex))); - } - - boolean checkDoubles = false; - boolean incCounter = true; - int counterOccur = 1; - for (Pair childClass : childClasses) { - String leftSide = (String) childClass.left(); - int rightSide = (int) childClass.right(); - if (leftSide.equals(classTag) && rightSide != indexNumber) { - checkDoubles = true; - if (incCounter) { - counterOccur++; - } - } - else if (leftSide.equals(classTag) && rightSide == indexNumber) { - incCounter = false; - } - } - - if (checkDoubles) { - String xpathComponent = "/" + classTag + "[" + counterOccur + "]"; - sb.insert(0, xpathComponent); - } - else { - String xpathComponent = "/" + classTag; - sb.insert(0, xpathComponent); - } - - } - - int indexBackSlash = sb.indexOf("/", sb.indexOf("/") + 1); - if (indexBackSlash > 0) { - String appName = IOSAppiumFramework.getAppName(); - String insertString = "[@name=\"" + appName + "\"]"; - sb.insert(indexBackSlash, insertString); - } - - sb.insert(0, "/"); - - return sb.toString(); - } - -} diff --git a/ios/src/org/testar/monkey/alayer/ios/IOSStateFetcher.java b/ios/src/org/testar/monkey/alayer/ios/IOSStateFetcher.java index 181e03bf0..2214e4825 100644 --- a/ios/src/org/testar/monkey/alayer/ios/IOSStateFetcher.java +++ b/ios/src/org/testar/monkey/alayer/ios/IOSStateFetcher.java @@ -1,7 +1,7 @@ /*************************************************************************************************** * - * Copyright (c) 2020 - 2022 Universitat Politecnica de Valencia - www.upv.es - * Copyright (c) 2020 - 2022 Open Universiteit - www.ou.nl + * Copyright (c) 2020 - 2026 Universitat Politecnica de Valencia - www.upv.es + * Copyright (c) 2020 - 2026 Open Universiteit - www.ou.nl * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -35,6 +35,7 @@ import org.testar.monkey.alayer.exceptions.StateBuildException; import org.testar.monkey.alayer.ios.enums.IOSTags; import org.testar.monkey.alayer.ios.util.IOSNodeParser; +import org.testar.monkey.alayer.ios.util.IOSXpathUtil; import org.w3c.dom.Document; import org.w3c.dom.Node; @@ -86,7 +87,7 @@ public IOSState call() throws Exception { for (Widget w : root) { w.set(Tags.Path, Util.indexString(w)); - w.set(IOSTags.iosXpath, IOSProtocolUtil.constructXpath(w)); + w.set(IOSTags.iosXpath, IOSXpathUtil.constructXpath(w)); } // get end time diff --git a/ios/src/org/testar/monkey/alayer/ios/spy_visualization/MobileVisualizationIOS.java b/ios/src/org/testar/monkey/alayer/ios/spy_visualization/MobileVisualizationIOS.java index 23ba1664f..cb2bcdfdf 100644 --- a/ios/src/org/testar/monkey/alayer/ios/spy_visualization/MobileVisualizationIOS.java +++ b/ios/src/org/testar/monkey/alayer/ios/spy_visualization/MobileVisualizationIOS.java @@ -1,7 +1,7 @@ /*************************************************************************************************** * - * Copyright (c) 2020 - 2022 Open Universiteit - www.ou.nl - * Copyright (c) 2020 - 2022 Universitat Politecnica de Valencia - www.upv.es + * Copyright (c) 2020 - 2026 Open Universiteit - www.ou.nl + * Copyright (c) 2020 - 2026 Universitat Politecnica de Valencia - www.upv.es * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -31,7 +31,7 @@ package org.testar.monkey.alayer.ios.spy_visualization; import org.testar.monkey.alayer.State; -import org.testar.monkey.alayer.ios.IOSProtocolUtil; +import org.testar.monkey.alayer.ios.util.IOSScreenshotUtil; import javax.swing.*; import java.awt.event.ActionEvent; @@ -136,7 +136,7 @@ private void updateScreen() { // Updates screenshot and overlay LocalTime startTime = LocalTime.now(); System.out.println("start updateScreen spy mode: " + startTime); - String screenshotPath = IOSProtocolUtil.getStateshotSpyMode(usedState); + String screenshotPath = IOSScreenshotUtil.getStateshotSpyMode(usedState); imagePanel.updateSc(screenshotPath, treeVizInstance.tree); LocalTime endTime = LocalTime.now(); System.out.println("end updateScreen spy mode: " + endTime); diff --git a/ios/src/org/testar/monkey/alayer/ios/util/IOSScreenshotUtil.java b/ios/src/org/testar/monkey/alayer/ios/util/IOSScreenshotUtil.java new file mode 100644 index 000000000..b1657d0ed --- /dev/null +++ b/ios/src/org/testar/monkey/alayer/ios/util/IOSScreenshotUtil.java @@ -0,0 +1,87 @@ +/*************************************************************************************************** + * + * Copyright (c) 2020 - 2026 Universitat Politecnica de Valencia - www.upv.es + * Copyright (c) 2020 - 2026 Open Universiteit - www.ou.nl + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *******************************************************************************************************/ + +package org.testar.monkey.alayer.ios.util; + +import java.io.IOException; +import java.util.Objects; + +import org.testar.monkey.alayer.AWTCanvas; +import org.testar.monkey.alayer.Action; +import org.testar.monkey.alayer.State; +import org.testar.monkey.alayer.Tags; +import org.testar.monkey.alayer.ios.IOSAppiumFramework; +import org.testar.util.ScreenshotUtil; + +public class IOSScreenshotUtil { + + private IOSScreenshotUtil() { + } + + public static String getActionshot(State state, Action action) { + Objects.requireNonNull(state, "State cannot be null"); + Objects.requireNonNull(action, "Action cannot be null"); + try { + return IOSAppiumFramework.getScreenshotAction(state, action); + } catch(Exception e) { + System.err.println("Exception when taking action screenshot: " + e); + } + + return ""; + } + + public static String getStateshotSpyMode(State state) { + Objects.requireNonNull(state, "State cannot be null"); + try { + return IOSAppiumFramework.getScreenshotSpyMode(state.get(Tags.ConcreteID, "NoConcreteIdAvailable")); + } catch(Exception e) { + System.err.println("Exception occured when trying to take a screenshot of the iOS emulator: " + e); + } + + return ""; + } + + /** + * Method returns a binary representation of a state's screenshot. + * @param state + * @return + */ + public static AWTCanvas getStateshotBinary(State state) { + Objects.requireNonNull(state, "State cannot be null"); + try { + return IOSAppiumFramework.getScreenshotBinary(state); + } catch (IOException e) { + System.err.println("Exception occured when trying to take a binary screenshot of the iOS emulator: " + e); + } + + return ScreenshotUtil.getStateshotBinary(state); + } + +} diff --git a/ios/src/org/testar/monkey/alayer/ios/util/IOSXpathUtil.java b/ios/src/org/testar/monkey/alayer/ios/util/IOSXpathUtil.java new file mode 100644 index 000000000..b567e03e4 --- /dev/null +++ b/ios/src/org/testar/monkey/alayer/ios/util/IOSXpathUtil.java @@ -0,0 +1,112 @@ +/*************************************************************************************************** + * + * Copyright (c) 2020 - 2026 Universitat Politecnica de Valencia - www.upv.es + * Copyright (c) 2020 - 2026 Open Universiteit - www.ou.nl + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *******************************************************************************************************/ + +package org.testar.monkey.alayer.ios.util; + +import java.util.ArrayList; + +import org.testar.monkey.Pair; +import org.testar.monkey.alayer.Tags; +import org.testar.monkey.alayer.Widget; +import org.testar.monkey.alayer.ios.IOSAppiumFramework; +import org.testar.monkey.alayer.ios.enums.IOSTags; + +public class IOSXpathUtil { + + private IOSXpathUtil() { + } + + // Method which constructs the hierachy xpath (absolute path) + // This method is needed as this is the only way to uniquely identify an GUI object if it has no accessibilityID. + //TODO: THIS METHOD IS VERY INEFFICIENT! Seems to work correctly though. + public static String constructXpath(Widget w) { + StringBuilder sb = new StringBuilder(); + Widget parentWidget = w; + + while (parentWidget != w.root()) { + String classTag = parentWidget.get(Tags.Desc, "*"); + int indexNumber = parentWidget.get(IOSTags.iosNodeIndex, -1); + + if (classTag.equals("Root")) { + break; + } + + parentWidget = parentWidget.parent(); + + ArrayList> childClasses = new ArrayList<>(); + + for (int i = 0; i < parentWidget.childCount(); i++) { + childClasses.add(new Pair( + parentWidget.child(i).get(Tags.Desc, "*"), + parentWidget.child(i).get(IOSTags.iosNodeIndex, -1) + )); + } + + boolean checkDoubles = false; + boolean incCounter = true; + int counterOccur = 1; + for (Pair childClass : childClasses) { + String leftSide = (String) childClass.left(); + int rightSide = (int) childClass.right(); + if (leftSide.equals(classTag) && rightSide != indexNumber) { + checkDoubles = true; + if (incCounter) { + counterOccur++; + } + } + else if (leftSide.equals(classTag) && rightSide == indexNumber) { + incCounter = false; + } + } + + if (checkDoubles) { + String xpathComponent = "/" + classTag + "[" + counterOccur + "]"; + sb.insert(0, xpathComponent); + } + else { + String xpathComponent = "/" + classTag; + sb.insert(0, xpathComponent); + } + + } + + int indexBackSlash = sb.indexOf("/", sb.indexOf("/") + 1); + if (indexBackSlash > 0) { + String appName = IOSAppiumFramework.getAppName(); + String insertString = "[@name=\"" + appName + "\"]"; + sb.insert(indexBackSlash, insertString); + } + + sb.insert(0, "/"); + + return sb.toString(); + } + +} diff --git a/linux/build.gradle b/linux/build.gradle deleted file mode 100644 index 1bd13b7d4..000000000 --- a/linux/build.gradle +++ /dev/null @@ -1,5 +0,0 @@ -dependencies { - implementation files('./lib/libatspi.jar') - implementation files('./lib/junit-jupiter-api-5.0.0-M3.jar') - implementation project(':core') -} \ No newline at end of file diff --git a/linux/lib/junit-jupiter-api-5.0.0-M3.jar b/linux/lib/junit-jupiter-api-5.0.0-M3.jar deleted file mode 100644 index ac895e738..000000000 Binary files a/linux/lib/junit-jupiter-api-5.0.0-M3.jar and /dev/null differ diff --git a/linux/lib/libX11.jar b/linux/lib/libX11.jar deleted file mode 100644 index f6ed12d15..000000000 Binary files a/linux/lib/libX11.jar and /dev/null differ diff --git a/linux/lib/libatspi.jar b/linux/lib/libatspi.jar deleted file mode 100644 index ca251058f..000000000 Binary files a/linux/lib/libatspi.jar and /dev/null differ diff --git a/linux/lib/libgdiplus.jar b/linux/lib/libgdiplus.jar deleted file mode 100644 index dabfe208b..000000000 Binary files a/linux/lib/libgdiplus.jar and /dev/null differ diff --git a/linux/lib/libgtk-3.jar b/linux/lib/libgtk-3.jar deleted file mode 100644 index 9bb372086..000000000 Binary files a/linux/lib/libgtk-3.jar and /dev/null differ diff --git a/linux/lib/libwnck-3.jar b/linux/lib/libwnck-3.jar deleted file mode 100644 index c74aff60d..000000000 Binary files a/linux/lib/libwnck-3.jar and /dev/null differ diff --git a/linux/lib/opentest4j-1.0.0-M1.jar b/linux/lib/opentest4j-1.0.0-M1.jar deleted file mode 100644 index 4601e3266..000000000 Binary files a/linux/lib/opentest4j-1.0.0-M1.jar and /dev/null differ diff --git a/linux/src/org/testar/monkey/alayer/linux/AtSpiElement.java b/linux/src/org/testar/monkey/alayer/linux/AtSpiElement.java deleted file mode 100644 index dd090dfb5..000000000 --- a/linux/src/org/testar/monkey/alayer/linux/AtSpiElement.java +++ /dev/null @@ -1,189 +0,0 @@ -/*************************************************************************************************** -* -* Copyright (c) 2017 Open Universiteit - www.ou.nl -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, -* this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the copyright holder nor the names of its -* contributors may be used to endorse or promote products derived from -* this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -* POSSIBILITY OF SUCH DAMAGE. -*******************************************************************************************************/ - - -package org.testar.monkey.alayer.linux; - - -import org.testar.monkey.alayer.Rect; -import org.testar.monkey.alayer.linux.atspi.enums.AtSpiRoles; -import org.testar.monkey.alayer.linux.enums.AtSpiElementOrientations; - -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.io.Serializable; -import java.util.ArrayList; -import java.util.List; - - -/** - * Represents an AT-SPI node that can be used by Testar. - */ -public class AtSpiElement implements Serializable { - - - //region Properties - - - public AtSpiElement parent; - List children = new ArrayList<>(); - - - public AtSpiRootElement root; - - - /** - * Reference to the AtSpiWidget this AtSpiElement is linked to in the State (widget tree) object created by AtSpiStateFetcher. - */ - AtSpiWidget backRef; - - - //region General AT-SPI information - - - long accessiblePtr; - public String name, description, toolkitName; - public AtSpiRoles role; - Rect boundingBoxOnScreen; - - - //endregion - - - //region AT-SPI State information - - - boolean isEnabled, hasFocus, isFocusable, isModal, isBlocked; - AtSpiElementOrientations orientation; - - - //endregion - - - //region Inferred information - - - boolean canScrollHorizontally, canScrollVertically, isTopLevelContainer, canScroll; - double zIndex, hScrollViewSizePercentage, vScrollViewSizePercentage, hScrollPercentage, vScrollPercentage; - - - //endregion - - - //region Miscellaneous information - - - /** - * Specifies that this element should be ignored since it contains invalid information or - * does not hold enough information for Testar to operate successfully. - */ - boolean ignore; - - - //endregion - - - //endregion - - - //region Constructors - - - /** - * Default constructor with a parent specified. - * @param parent The parent of this AT-SPI element. - */ - AtSpiElement(AtSpiElement parent) { - - this.parent = parent; - - if (parent != null) { - root = parent.root; - } - - } - - - //endregion - - - //region Serializable functionality - - - // Used to determine the class during serialization. - private static final long serialVersionUID = 159753654852L; - - - // Most likely used to serialize and deserialize an instance of this class - don't know if this is used by Testar though. - - - - /** - * Serialize an instance of this object. - * @param oos The outputstream to write to. - * @throws IOException An IO error occurred. - */ - private void writeObject(ObjectOutputStream oos) throws IOException { - oos.defaultWriteObject(); - } - - - /** - * Deserialize an instance of this object. - * @param ois The inputstream to write to. - * @throws IOException An IO error occurred. - * @throws ClassNotFoundException Class could not be found. - */ - private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException{ - ois.defaultReadObject(); - } - - - //endregion - - - //region Object overrides - - - @Override - public String toString() { - if (role != null) { - return "Name: " + name + " - Role: " + role.toString() + " - Children: " + children.size(); - } else { - return "Name: " + name + " - Children: " + children.size(); - } - - } - - - //endregion - - -} diff --git a/linux/src/org/testar/monkey/alayer/linux/AtSpiElementComparer.java b/linux/src/org/testar/monkey/alayer/linux/AtSpiElementComparer.java deleted file mode 100644 index 0456c046f..000000000 --- a/linux/src/org/testar/monkey/alayer/linux/AtSpiElementComparer.java +++ /dev/null @@ -1,74 +0,0 @@ -/*************************************************************************************************** -* -* Copyright (c) 2017 Open Universiteit - www.ou.nl -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, -* this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the copyright holder nor the names of its -* contributors may be used to endorse or promote products derived from -* this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -* POSSIBILITY OF SUCH DAMAGE. -*******************************************************************************************************/ - -package org.testar.monkey.alayer.linux; - -import org.testar.monkey.alayer.Rect; - -import java.util.Comparator; - - -/** - * Compares two AtSpiElements - used when sorting a list of AtSpiElements. - */ -public class AtSpiElementComparer implements Comparator { - - - private final static int WORSE = 1, BETTER = -1, EVEN = 0; - - - /** - * Compares two AtSpiElements and returns a result to be able to sort the elements in a list. - * @param o1 The first AtSpiElement. - * @param o2 The second AtSpiElement. - * @return 1 if worse, -1 if better, 0 if even. - */ - @Override - public int compare(AtSpiElement o1, AtSpiElement o2) { - if(o1.zIndex < o2.zIndex){ - return WORSE; - }else if (o1.zIndex > o2.zIndex){ - return BETTER; - }else{ - if(o1.boundingBoxOnScreen != null){ - if(o2.boundingBoxOnScreen != null){ - double area1 = Rect.area(o1.boundingBoxOnScreen); - double area2 = Rect.area(o2.boundingBoxOnScreen); - return area1 < area2 ? BETTER : (area1 > area2 ? WORSE : EVEN); - }else{ - return BETTER; - } - }else{ - return WORSE; - } - } - } - - -} diff --git a/linux/src/org/testar/monkey/alayer/linux/AtSpiElementMap.java b/linux/src/org/testar/monkey/alayer/linux/AtSpiElementMap.java deleted file mode 100644 index 89c3e8e48..000000000 --- a/linux/src/org/testar/monkey/alayer/linux/AtSpiElementMap.java +++ /dev/null @@ -1,126 +0,0 @@ -/*************************************************************************************************** -* -* Copyright (c) 2017 Open Universiteit - www.ou.nl -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, -* this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the copyright holder nor the names of its -* contributors may be used to endorse or promote products derived from -* this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -* POSSIBILITY OF SUCH DAMAGE. -*******************************************************************************************************/ - - -package org.testar.monkey.alayer.linux; - -import org.testar.monkey.Assert; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.List; - - -/** - * Data structure representing a mapping of AtSpiElements to be something - only used for AtSpiElements - * that are TopLevelContainers. - * - * This map could (perhaps should) be made generic... - */ -public class AtSpiElementMap implements Serializable { - - - // Used to determine the class during serialization. - private static final long serialVersionUID = 444555666888222999L; - - - //region Properties - - - private final List elements = new ArrayList<>(); - - - //endregion - - - //region Constructors - - - /** - * Default empty constructor. - */ - AtSpiElementMap(){ - - } - - - //endregion - - - //region Map functionality - This used to be in the ElementMapBuilder - - - /** - * Tries to add an element to the map. - * @param element The element to add to the map. - */ - void addElement(AtSpiElement element) { - - Assert.notNull(element); - - if (element.boundingBoxOnScreen != null) { - elements.add(element); - } - - } - - - /** - * Sorts the elements in the map. - */ - void sort() { - elements.sort(new AtSpiElementComparer()); - } - - - //endregion - - - //region Functionality used by AtSpiRootElement -> AtSpiHitTester - - - /** - * Gets the first top level container element that encompasses a certain point on the screen. - * @param x The x-coordinate of the point to encompass. - * @param y The y-coordinate of the point to encompass. - * @return The first top level container element that encompasses a certain point on the screen. - */ - public AtSpiElement at(double x, double y){ - for(AtSpiElement element : elements){ - if(element.boundingBoxOnScreen.contains(x, y)) - return element; - } - return null; - } - - - //endregion - - -} diff --git a/linux/src/org/testar/monkey/alayer/linux/AtSpiHitTester.java b/linux/src/org/testar/monkey/alayer/linux/AtSpiHitTester.java deleted file mode 100644 index f73dc0c2d..000000000 --- a/linux/src/org/testar/monkey/alayer/linux/AtSpiHitTester.java +++ /dev/null @@ -1,121 +0,0 @@ -/*************************************************************************************************** -* -* Copyright (c) 2017 Open Universiteit - www.ou.nl -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, -* this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the copyright holder nor the names of its -* contributors may be used to endorse or promote products derived from -* this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -* POSSIBILITY OF SUCH DAMAGE. -*******************************************************************************************************/ - - -package org.testar.monkey.alayer.linux; - - -import org.testar.monkey.alayer.HitTester; - - -/** - * An object that can execute an hit test action on an AtSpiElement - determining if the element can be clicked on - * at a certain point on the screen. - */ -public class AtSpiHitTester implements HitTester { - - - //region Global variables - - - // Used to determine the class during serialization. - private static final long serialVersionUID = 3216549871296454556L; - - - private final AtSpiElement _element; - - - //endregion - - - //region Constructors - - - /** - * Default constructor wrapping an AtSpiElement to hit test. - * @param element The AtSpiElement to hit test. - */ - AtSpiHitTester(AtSpiElement element) { - _element = element; - } - - - //endregion - - - //region HitTester implementation - - - /** - * Runs the hit test action for a certain point on the element. - * @param x The x-coordiante of the point. - * @param y The y-coordinate of the point. - * @return True if the element can be hit at the supplied point on the screen; False otherwise. - */ - @Override - public boolean apply(double x, double y) { - return _element.root.visibleAt(_element, x, y); - } - - - /** - * Runs the hit test action for a certain point on the element. - * @param x The x-coordiante of the point. - * @param y The y-coordinate of the point. - * @param obscuredByChildFeature The element is obscured by a child?? - * @return True if the element can be hit at the supplied point on the screen; False otherwise. - */ - @Override - public boolean apply(double x, double y, boolean obscuredByChildFeature) { - return _element.root.visibleAt(_element, x, y, obscuredByChildFeature); - } - - - //endregion - - - //region Object overrides - - - @Override - public String toString() { - - if (_element == null) { - return "AtSpiHitTester"; - } else { - return "AtSpiHitTester for: " + _element.name + " bounding: " + _element.boundingBoxOnScreen.toString(); - } - - } - - - //endregion - - -} diff --git a/linux/src/org/testar/monkey/alayer/linux/AtSpiRolesWrapper.java b/linux/src/org/testar/monkey/alayer/linux/AtSpiRolesWrapper.java deleted file mode 100644 index 1dc336f79..000000000 --- a/linux/src/org/testar/monkey/alayer/linux/AtSpiRolesWrapper.java +++ /dev/null @@ -1,234 +0,0 @@ -/*************************************************************************************************** -* -* Copyright (c) 2017 Open Universiteit - www.ou.nl -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, -* this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the copyright holder nor the names of its -* contributors may be used to endorse or promote products derived from -* this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -* POSSIBILITY OF SUCH DAMAGE. -*******************************************************************************************************/ - - -package org.testar.monkey.alayer.linux; - - -import org.testar.monkey.Util; -import org.testar.monkey.alayer.Role; -import org.testar.monkey.alayer.Roles; -import org.testar.monkey.alayer.linux.atspi.enums.AtSpiRoles; - -import java.util.Map; - - -/** - * Wraps native roles - it maps the native At-SPI roles to Testar defined ones. - */ -public final class AtSpiRolesWrapper { - - - //region Variables - - - // The mapping of the navive Role wrappers with an ID (the AtSpiRoles enum value). - private final static Map typeIdToRole = Util.newHashMap(); - - - // Define all native role wrappers. - public static final Role - - // First the non-existent - they are defined purely to better map with Testar. - AtSpiWidget = from(-1, "AtSpiWidget", Roles.Widget), - - // The rest maps AtSpiRoles enum ids to a custom name and a Testar defined (parent) Role(s). - AtSpiInvalid = from(AtSpiRoles.Invalid.ordinal(), "AtSpi" + AtSpiRoles.Invalid.toString(), Roles.Invalid), - AtSpiAcceleratorLabel = from(AtSpiRoles.AcceleratorLabel.ordinal(), "AtSpi" + AtSpiRoles.AcceleratorLabel.toString(), AtSpiWidget, Roles.Control), - AtSpiAlert = from(AtSpiRoles.Alert.ordinal(), "AtSpi" + AtSpiRoles.Alert.toString(), AtSpiWidget, Roles.Control), - AtSpiAnimation = from(AtSpiRoles.Animation.ordinal(), "AtSpi" + AtSpiRoles.Animation.toString(), AtSpiWidget, Roles.Control), - AtSpiArrow = from(AtSpiRoles.Arrow.ordinal(), "AtSpi" + AtSpiRoles.Arrow.toString(), AtSpiWidget, Roles.Control), - AtSpiCalendar = from(AtSpiRoles.Calendar.ordinal(), "AtSpi" + AtSpiRoles.Calendar.toString(), AtSpiWidget, Roles.Control), - AtSpiCanvas = from(AtSpiRoles.Canvas.ordinal(), "AtSpi" + AtSpiRoles.Canvas.toString(), AtSpiWidget, Roles.Control), - AtSpiCheckBox = from(AtSpiRoles.CheckBox.ordinal(), "AtSpi" + AtSpiRoles.CheckBox.toString(), AtSpiWidget, Roles.ToggleButton), - AtSpiCheckMenuItem = from(AtSpiRoles.CheckMenuItem.ordinal(), "AtSpi" + AtSpiRoles.CheckMenuItem.toString(), AtSpiWidget, Roles.ToggleButton), - AtSpiColorChooser = from(AtSpiRoles.ColorChooser.ordinal(), "AtSpi" + AtSpiRoles.ColorChooser.toString(), AtSpiWidget, Roles.Dialog), - AtSpiColumnHeader = from(AtSpiRoles.ColumnHeader.ordinal(), "AtSpi" + AtSpiRoles.ColumnHeader.toString(), AtSpiWidget, Roles.Control), - AtSpiComboBox = from(AtSpiRoles.ComboBox.ordinal(), "AtSpi" + AtSpiRoles.ComboBox.toString(), AtSpiWidget, Roles.ItemContainer), - AtSpiDateEditor = from(AtSpiRoles.DateEditor.ordinal(), "AtSpi" + AtSpiRoles.DateEditor.toString(), AtSpiWidget, Roles.Control), - AtSpiDesktopIcon = from(AtSpiRoles.DesktopIcon.ordinal(), "AtSpi" + AtSpiRoles.DesktopIcon.toString(), AtSpiWidget, Roles.Control), - AtSpiDesktopFrame = from(AtSpiRoles.DesktopFrame.ordinal(), "AtSpi" + AtSpiRoles.DesktopFrame.toString(), AtSpiWidget, Roles.Control), - AtSpiDial = from(AtSpiRoles.Dial.ordinal(), "AtSpi" + AtSpiRoles.Dial.toString(), AtSpiWidget, Roles.Control), - AtSpiDialog = from(AtSpiRoles.Dialog.ordinal(), "AtSpi" + AtSpiRoles.Dialog.toString(), AtSpiWidget, Roles.Dialog), - AtSpiDirectoryPane = from(AtSpiRoles.DirectoryPane.ordinal(), "AtSpi" + AtSpiRoles.DirectoryPane.toString(), AtSpiWidget, Roles.Control), - AtSpiDrawingArea = from(AtSpiRoles.DrawingArea.ordinal(), "AtSpi" + AtSpiRoles.DrawingArea.toString(), AtSpiWidget, Roles.Dialog), - AtSpiFileChooser = from(AtSpiRoles.FileChooser.ordinal(), "AtSpi" + AtSpiRoles.FileChooser.toString(), AtSpiWidget, Roles.Dialog), - AtSpiFiller = from(AtSpiRoles.Filler.ordinal(), "AtSpi" + AtSpiRoles.Filler.toString(), AtSpiWidget, Roles.Control), - AtSpiFocusTraversable = from(AtSpiRoles.FocusTraversable.ordinal(), "AtSpi" + AtSpiRoles.FocusTraversable.toString(), Roles.Invalid), - AtSpiFontChooser = from(AtSpiRoles.FontChooser.ordinal(), "AtSpi" + AtSpiRoles.FontChooser.toString(), AtSpiWidget, Roles.Dialog), - AtSpiFrame = from(AtSpiRoles.Frame.ordinal(), "AtSpi" + AtSpiRoles.Frame.toString(), AtSpiWidget, Roles.Control), - AtSpiGlassPane = from(AtSpiRoles.GlassPane.ordinal(), "AtSpi" + AtSpiRoles.GlassPane.toString(), AtSpiWidget, Roles.Control), - AtSpiHtmlContainer = from(AtSpiRoles.HTMLContainer.ordinal(), "AtSpi" + AtSpiRoles.HTMLContainer.toString(), AtSpiWidget, Roles.Control), - AtSpiIcon = from(AtSpiRoles.Icon.ordinal(), "AtSpi" + AtSpiRoles.Icon.toString(), AtSpiWidget, Roles.Control), - AtSpiImage = from(AtSpiRoles.Image.ordinal(), "AtSpi" + AtSpiRoles.Image.toString(), AtSpiWidget, Roles.Control), - AtSpiInternalFrame = from(AtSpiRoles.InternalFrame.ordinal(), "AtSpi" + AtSpiRoles.InternalFrame.toString(), AtSpiWidget, Roles.Control), - AtSpiLabel = from(AtSpiRoles.Label.ordinal(), "AtSpi" + AtSpiRoles.Label.toString(), AtSpiWidget, Roles.Text), - AtSpiLayeredPane = from(AtSpiRoles.LayeredPane.ordinal(), "AtSpi" + AtSpiRoles.LayeredPane.toString(), AtSpiWidget, Roles.Control), - AtSpiList = from(AtSpiRoles.List.ordinal(), "AtSpi" + AtSpiRoles.List.toString(), AtSpiWidget, Roles.ItemContainer), - AtSpiListItem = from(AtSpiRoles.ListItem.ordinal(), "AtSpi" + AtSpiRoles.ListItem.toString(), AtSpiWidget, Roles.Item), - AtSpiMenu = from(AtSpiRoles.Menu.ordinal(), "AtSpi" + AtSpiRoles.Menu.toString(), AtSpiWidget, Roles.ItemContainer), - AtSpiMenuBar = from(AtSpiRoles.MenuBar.ordinal(), "AtSpi" + AtSpiRoles.MenuBar.toString(), AtSpiWidget, Roles.ItemContainer), - AtSpiMenuItem = from(AtSpiRoles.MenuItem.ordinal(), "AtSpi" + AtSpiRoles.MenuItem.toString(), AtSpiWidget, Roles.Item), - AtSpiOptionPane = from(AtSpiRoles.OptionPane.ordinal(), "AtSpi" + AtSpiRoles.OptionPane.toString(), AtSpiWidget, Roles.Control), - AtSpiPageTab = from(AtSpiRoles.PageTab.ordinal(), "AtSpi" + AtSpiRoles.PageTab.toString(), AtSpiWidget, Roles.Control), - AtSpiPageTabList = from(AtSpiRoles.PageTabList.ordinal(), "AtSpi" + AtSpiRoles.PageTabList.toString(), AtSpiWidget, Roles.Control), - AtSpiPanel = from(AtSpiRoles.Panel.ordinal(), "AtSpi" + AtSpiRoles.Panel.toString(), AtSpiWidget, Roles.Control), - AtSpiPasswordText = from(AtSpiRoles.PasswordText.ordinal(), "AtSpi" + AtSpiRoles.PasswordText.toString(), AtSpiWidget, Roles.Text), - AtSpiPopupMenu = from(AtSpiRoles.PopupMenu.ordinal(), "AtSpi" + AtSpiRoles.PopupMenu.toString(), AtSpiWidget, Roles.Control), - AtSpiProgressBar = from(AtSpiRoles.ProgressBar.ordinal(), "AtSpi" + AtSpiRoles.ProgressBar.toString(), AtSpiWidget, Roles.Control), - AtSpiPushButton = from(AtSpiRoles.PushButton.ordinal(), "AtSpi" + AtSpiRoles.PushButton.toString(), AtSpiWidget, Roles.Button), - AtSpiRadioButton = from(AtSpiRoles.RadioButton.ordinal(), "AtSpi" + AtSpiRoles.RadioButton.toString(), AtSpiWidget, Roles.ToggleButton, Roles.ItemContainer), - AtSpiRadioButtonMenuItem = from(AtSpiRoles.RadioMenuItem.ordinal(), "AtSpi" + AtSpiRoles.RadioMenuItem.toString(), AtSpiWidget, Roles.Item), - AtSpiRootPane = from(AtSpiRoles.RootPane.ordinal(), "AtSpi" + AtSpiRoles.RootPane.toString(), AtSpiWidget, Roles.Control), - AtSpiRowHeader = from(AtSpiRoles.RowHeader.ordinal(), "AtSpi" + AtSpiRoles.RowHeader.toString(), AtSpiWidget, Roles.Control), - AtSpiScrollBar = from(AtSpiRoles.ScrollBar.ordinal(), "AtSpi" + AtSpiRoles.ScrollBar.toString(), AtSpiWidget, Roles.Control), - AtSpiScrollPane = from(AtSpiRoles.ScrollPane.ordinal(), "AtSpi" + AtSpiRoles.ScrollPane.toString(), AtSpiWidget, Roles.Control), - AtSpiSeparator = from(AtSpiRoles.Separator.ordinal(), "AtSpi" + AtSpiRoles.Separator.toString(), AtSpiWidget, Roles.Control), - AtSpiSlider = from(AtSpiRoles.Slider.ordinal(), "AtSpi" + AtSpiRoles.Slider.toString(), AtSpiWidget, Roles.Slider), - AtSpiSpinButton = from(AtSpiRoles.SpinButton.ordinal(), "AtSpi" + AtSpiRoles.SpinButton.toString(), AtSpiWidget, Roles.Button), - AtSpiSplitPane = from(AtSpiRoles.SplitPane.ordinal(), "AtSpi" + AtSpiRoles.SplitPane.toString(), AtSpiWidget, Roles.Control), - AtSpiStatusBar = from(AtSpiRoles.StatusBar.ordinal(), "AtSpi" + AtSpiRoles.StatusBar.toString(), AtSpiWidget, Roles.Control), - AtSpiTable = from(AtSpiRoles.Table.ordinal(), "AtSpi" + AtSpiRoles.Table.toString(), AtSpiWidget, Roles.Control), - AtSpiTableCell = from(AtSpiRoles.TableCell.ordinal(), "AtSpi" + AtSpiRoles.TableCell.toString(), AtSpiWidget, Roles.Control), - AtSpiTableColumnHeader = from(AtSpiRoles.TableColumnHeader.ordinal(), "AtSpi" + AtSpiRoles.TableColumnHeader.toString(), AtSpiWidget, Roles.Control), - AtSpiTableRowHeader = from(AtSpiRoles.TableRowHeader.ordinal(), "AtSpi" + AtSpiRoles.TableRowHeader.toString(), AtSpiWidget, Roles.Control), - AtSpiTearOffMenuItem = from(AtSpiRoles.TearoffMenuItem.ordinal(), "AtSpi" + AtSpiRoles.TearoffMenuItem.toString(), AtSpiWidget, Roles.ItemContainer), - AtSpiTerminal = from(AtSpiRoles.Terminal.ordinal(), "AtSpi" + AtSpiRoles.Terminal.toString(), AtSpiWidget, Roles.Control), - AtSpiText = from(AtSpiRoles.Text.ordinal(), "AtSpi" + AtSpiRoles.Text.toString(), AtSpiWidget, Roles.Text), - AtSpiToggleButton = from(AtSpiRoles.ToggleButton.ordinal(), "AtSpi" + AtSpiRoles.ToggleButton.toString(), AtSpiWidget, Roles.ToggleButton), - AtSpiToolBar = from(AtSpiRoles.ToolBar.ordinal(), "AtSpi" + AtSpiRoles.ToolBar.toString(), AtSpiWidget, Roles.Control), - AtSpiToolTip = from(AtSpiRoles.ToolTip.ordinal(), "AtSpi" + AtSpiRoles.ToolTip.toString(), AtSpiWidget, Roles.Text), - AtSpiTree = from(AtSpiRoles.Tree.ordinal(), "AtSpi" + AtSpiRoles.Tree.toString(), AtSpiWidget, Roles.Control), - AtSpiTreeTable = from(AtSpiRoles.TreeTable.ordinal(), "AtSpi" + AtSpiRoles.TreeTable.toString(), AtSpiWidget, Roles.Control), - AtSpiUnknown = from(AtSpiRoles.Unknown.ordinal(), "AtSpi" + AtSpiRoles.Unknown.toString(), AtSpiWidget, Roles.Control), - AtSpiViewport = from(AtSpiRoles.Viewport.ordinal(), "AtSpi" + AtSpiRoles.Viewport.toString(), AtSpiWidget, Roles.Control), - AtSpiWindow = from(AtSpiRoles.Window.ordinal(), "AtSpi" + AtSpiRoles.Window.toString(), AtSpiWidget, Roles.Control), - AtSpiExtended = from(AtSpiRoles.Extended.ordinal(), "AtSpi" + AtSpiRoles.Extended.toString(), AtSpiWidget, Roles.Control), - AtSpiHeader = from(AtSpiRoles.Header.ordinal(), "AtSpi" + AtSpiRoles.Header.toString(), AtSpiWidget, Roles.Control), - AtSpiFooter = from(AtSpiRoles.Footer.ordinal(), "AtSpi" + AtSpiRoles.Footer.toString(), AtSpiWidget, Roles.Control), - AtSpiParagraph = from(AtSpiRoles.Paragraph.ordinal(), "AtSpi" + AtSpiRoles.Paragraph.toString(), AtSpiWidget, Roles.Control), - AtSpiRuler = from(AtSpiRoles.Ruler.ordinal(), "AtSpi" + AtSpiRoles.Ruler.toString(), AtSpiWidget, Roles.Control), - AtSpiApplication = from(AtSpiRoles.Application.ordinal(), "AtSpi" + AtSpiRoles.Application.toString(), AtSpiWidget, Roles.Control, Roles.System), - AtSpiAutoComplete = from(AtSpiRoles.Autocomplete.ordinal(), "AtSpi" + AtSpiRoles.Autocomplete.toString(), AtSpiWidget, Roles.Control), - AtSpiEditBar = from(AtSpiRoles.EditBar.ordinal(), "AtSpi" + AtSpiRoles.EditBar.toString(), AtSpiWidget, Roles.Text), - AtSpiEmbedded = from(AtSpiRoles.Embedded.ordinal(), "AtSpi" + AtSpiRoles.Embedded.toString(), AtSpiWidget, Roles.Control), - AtSpiEntry = from(AtSpiRoles.Entry.ordinal(), "AtSpi" + AtSpiRoles.Entry.toString(), AtSpiWidget, Roles.Control), - AtSpiChart = from(AtSpiRoles.Chart.ordinal(), "AtSpi" + AtSpiRoles.Chart.toString(), AtSpiWidget, Roles.Control), - AtSpiCaption = from(AtSpiRoles.Caption.ordinal(), "AtSpi" + AtSpiRoles.Caption.toString(), AtSpiWidget, Roles.Control), - AtSpiDocumentFrame = from(AtSpiRoles.DocumentFrame.ordinal(), "AtSpi" + AtSpiRoles.DocumentFrame.toString(), AtSpiWidget, Roles.Control), - AtSpiHeading = from(AtSpiRoles.Heading.ordinal(), "AtSpi" + AtSpiRoles.Heading.toString(), AtSpiWidget, Roles.Text), - AtSpiPage = from(AtSpiRoles.Page.ordinal(), "AtSpi" + AtSpiRoles.Page.toString(), AtSpiWidget, Roles.Control), - AtSpiSection = from(AtSpiRoles.Section.ordinal(), "AtSpi" + AtSpiRoles.Section.toString(), AtSpiWidget, Roles.Control), - AtSpiRedundantObject = from(AtSpiRoles.RedundantObject.ordinal(), "AtSpi" + AtSpiRoles.RedundantObject.toString(), AtSpiWidget, Roles.Control), - AtSpiForm = from(AtSpiRoles.Form.ordinal(), "AtSpi" + AtSpiRoles.Form.toString(), AtSpiWidget, Roles.Control), - AtSpiLink = from(AtSpiRoles.Link.ordinal(), "AtSpi" + AtSpiRoles.Link.toString(), AtSpiWidget, Roles.Text), - AtSpiInputMethodWindow = from(AtSpiRoles.InputMethodWindow.ordinal(), "AtSpi" + AtSpiRoles.InputMethodWindow.toString(), AtSpiWidget, Roles.Control), - AtSpiTableRow = from(AtSpiRoles.TableRow.ordinal(), "AtSpi" + AtSpiRoles.TableRow.toString(), AtSpiWidget, Roles.Control), - AtSpiTreeItem = from(AtSpiRoles.TreeItem.ordinal(), "AtSpi" + AtSpiRoles.TreeItem.toString(), AtSpiWidget, Roles.Item), - AtSpiDocumentSpreadsheet = from(AtSpiRoles.DocumentSpreadsheet.ordinal(), "AtSpi" + AtSpiRoles.DocumentSpreadsheet.toString(), AtSpiWidget, Roles.Control), - AtSpiDocumentPresentation = from(AtSpiRoles.DocumentPresentation.ordinal(), "AtSpi" + AtSpiRoles.DocumentPresentation.toString(), AtSpiWidget, Roles.Control), - AtSpiDocumentText = from(AtSpiRoles.DocumentText.ordinal(), "AtSpi" + AtSpiRoles.DocumentText.toString(), AtSpiWidget, Roles.Text), - AtSpiDocumentWeb = from(AtSpiRoles.DocumentWeb.ordinal(), "AtSpi" + AtSpiRoles.DocumentWeb.toString(), AtSpiWidget, Roles.Text), - AtSpiDocumentEmail = from(AtSpiRoles.DocumentEmail.ordinal(), "AtSpi" + AtSpiRoles.DocumentEmail.toString(), AtSpiWidget, Roles.Text), - AtSpiComment = from(AtSpiRoles.Comment.ordinal(), "AtSpi" + AtSpiRoles.Comment.toString(), AtSpiWidget, Roles.Text), - AtSpiListBox = from(AtSpiRoles.ListBox.ordinal(), "AtSpi" + AtSpiRoles.ListBox.toString(), AtSpiWidget, Roles.ItemContainer), - AtSpiGrouping = from(AtSpiRoles.Grouping.ordinal(), "AtSpi" + AtSpiRoles.Grouping.toString(), AtSpiWidget, Roles.Control), - AtSpiImageMap = from(AtSpiRoles.ImageMap.ordinal(), "AtSpi" + AtSpiRoles.ImageMap.toString(), AtSpiWidget, Roles.Control), - AtSpiNotification = from(AtSpiRoles.Notification.ordinal(), "AtSpi" + AtSpiRoles.Notification.toString(), AtSpiWidget, Roles.Control), - AtSpiInfoBar = from(AtSpiRoles.InfoBar.ordinal(), "AtSpi" + AtSpiRoles.InfoBar.toString(), AtSpiWidget, Roles.Control), - AtSpiLevelBar = from(AtSpiRoles.LevelBar.ordinal(), "AtSpi" + AtSpiRoles.LevelBar.toString(), AtSpiWidget, Roles.Control), - AtSpiTitleBar = from(AtSpiRoles.TitleBar.ordinal(), "AtSpi" + AtSpiRoles.TitleBar.toString(), AtSpiWidget, Roles.Text), - AtSpiBlockQuote = from(AtSpiRoles.BlockQuote.ordinal(), "AtSpi" + AtSpiRoles.BlockQuote.toString(), AtSpiWidget, Roles.Control), - AtSpiAudio = from(AtSpiRoles.Audio.ordinal(), "AtSpi" + AtSpiRoles.Audio.toString(), AtSpiWidget, Roles.Control), - AtSpiVideo = from(AtSpiRoles.Video.ordinal(), "AtSpi" + AtSpiRoles.Video.toString(), AtSpiWidget, Roles.Control), - AtSpiDefinition = from(AtSpiRoles.Definition.ordinal(), "AtSpi" + AtSpiRoles.Definition.toString(), AtSpiWidget, Roles.Text), - AtSpiArticle = from(AtSpiRoles.Article.ordinal(), "AtSpi" + AtSpiRoles.Article.toString(), AtSpiWidget, Roles.Control), - AtSpiLandmark = from(AtSpiRoles.Landmark.ordinal(), "AtSpi" + AtSpiRoles.Landmark.toString(), AtSpiWidget, Roles.Control), - AtSpiLog = from(AtSpiRoles.Log.ordinal(), "AtSpi" + AtSpiRoles.Log.toString(), AtSpiWidget, Roles.Text), - AtSpiMarquee = from(AtSpiRoles.Marquee.ordinal(), "AtSpi" + AtSpiRoles.Marquee.toString(), AtSpiWidget, Roles.Control), - AtSpiMath = from(AtSpiRoles.Math.ordinal(), "AtSpi" + AtSpiRoles.Math.toString(), AtSpiWidget, Roles.Text), - AtSpiRating = from(AtSpiRoles.Rating.ordinal(), "AtSpi" + AtSpiRoles.Rating.toString(), AtSpiWidget, Roles.Control), - AtSpiTimer = from(AtSpiRoles.Timer.ordinal(), "AtSpi" + AtSpiRoles.Timer.toString(), AtSpiWidget, Roles.Control), - AtSpiStatic = from(AtSpiRoles.Static.ordinal(), "AtSpi" + AtSpiRoles.Static.toString(), AtSpiWidget, Roles.Control), - AtSpiMathFraction = from(AtSpiRoles.MathFraction.ordinal(), "AtSpi" + AtSpiRoles.MathFraction.toString(), AtSpiWidget, Roles.Control), - AtSpiMathRoot = from(AtSpiRoles.MathRoot.ordinal(), "AtSpi" + AtSpiRoles.MathRoot.toString(), AtSpiWidget, Roles.Control), - AtSpiSubscript = from(AtSpiRoles.Subscript.ordinal(), "AtSpi" + AtSpiRoles.Subscript.toString(), AtSpiWidget, Roles.Control), - AtSpiSuperscript = from(AtSpiRoles.Superscript.ordinal(), "AtSpi" + AtSpiRoles.Superscript.toString(), AtSpiWidget, Roles.Control), - AtSpiLastDefined = from(AtSpiRoles.LastDefined.ordinal(), "AtSpi" + AtSpiRoles.LastDefined.toString(), Roles.Invalid); - - - //endregion - - - //region Constructors - - - /** - * Default empty constructor. - */ - private AtSpiRolesWrapper() {} - - - //endregion - - - //region Helper functionality - - - // The Role... means Role[] - you can define as many Roles as you like when calling this method and - // the array will be created automatically. - /** - * Creates, adds to the internal type id map and returns a native role wrapper. - * @param id Id of the native role (AtSpiRoles enum value). - * @param name Friendly name of the native role. - * @param inheritFrom The parent(s) of the role. - * @return The wrapper for the native role. - */ - private static Role from(long id, String name, Role... inheritFrom){ - Role ret = Role.from(name, inheritFrom); - typeIdToRole.put(id, ret); - return ret; - } - - - /** - * Find a role belonging to a type id. - * @param typeId The type id of an AtSpiRole. - * @return The Role wrapping an AtSpiRole. - */ - public static Role fromTypeId(long typeId){ - Role ret = typeIdToRole.get(typeId); - return (ret == null) ? AtSpiUnknown : ret; - } - - - //endregion - - -} diff --git a/linux/src/org/testar/monkey/alayer/linux/AtSpiRootElement.java b/linux/src/org/testar/monkey/alayer/linux/AtSpiRootElement.java deleted file mode 100644 index e6a6f4a80..000000000 --- a/linux/src/org/testar/monkey/alayer/linux/AtSpiRootElement.java +++ /dev/null @@ -1,223 +0,0 @@ -/*************************************************************************************************** -* -* Copyright (c) 2017 Open Universiteit - www.ou.nl -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, -* this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the copyright holder nor the names of its -* contributors may be used to endorse or promote products derived from -* this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -* POSSIBILITY OF SUCH DAMAGE. -*******************************************************************************************************/ - - -package org.testar.monkey.alayer.linux; - - -import org.testar.monkey.Util; - -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.util.Map; - - -/** - * Represents an AT-SPI root (application) node that can be used by Testar. - */ -public class AtSpiRootElement extends AtSpiElement { - - - //region Properties - - - long pid, timeStamp; - - - boolean isRunning, isActive, hasStandardMouse, hasStandardKeyboard; - - - /** - * Contains a mapping of AtSpiAccessible pointers and their corresponding AtSpiElements. - */ - transient Map pointerMap; - - - AtSpiElementMap topLevelContainerMap; - - - //endregion - - - //region Constructor - - - /** - * Default constructor. - */ - AtSpiRootElement() { - super(null); - - root = this; - pointerMap = Util.newHashMap(); - topLevelContainerMap = new AtSpiElementMap(); - - } - - - //endregion - - - - //region Other needed functionality - Used by AtSpiHitTester - - - /** - * Determines whether an element encompasses a point on the screen. - * @param element The element that might encompasses the point on the screen. - * @param x The x-coordinate of the point. - * @param y The y-coordiante of the point. - * @return True if the element encompasses the point on screen; False otherwise. - */ - boolean visibleAt(AtSpiElement element, double x, double y){ - - - // The element doesn't encompass the point on the screen. - if(element.boundingBoxOnScreen == null || !element.boundingBoxOnScreen.contains(x, y) || !this.boundingBoxOnScreen.contains(x, y)) { - return false; - } - - - // Get the top level container encompassing the hit test point. - AtSpiElement topLevelContainer = topLevelContainerMap.at(x, y); - - - // Top level containers always have z-index of 0 (I think) - checks if element is obscured by children - // or a top level container. - return (topLevelContainer == null || topLevelContainer.zIndex <= element.zIndex) && - !obscuredByChildren(element, x, y); - - } - - - /** - * Determines whether an element encompasses a point on the screen. - * @param element The element that might encompasses the point on the screen. - * @param x The x-coordinate of the point. - * @param y The y-coordiante of the point. - * @param obscuredByChildFeature A child obscures the (parent) element?? - * @return True if the element encompasses the point on screen; False otherwise. - */ - boolean visibleAt(AtSpiElement element, double x, double y, boolean obscuredByChildFeature){ - - - // The element doesn't encompass the point on the screen. - if(element.boundingBoxOnScreen == null || !element.boundingBoxOnScreen.contains(x, y) || !this.boundingBoxOnScreen.contains(x, y)) { - return false; - } - - - // Get the top level container encompassing the hit test point. - AtSpiElement topLevelContainer = topLevelContainerMap.at(x, y); - - - // Top level containers always have z-index of 0 (I think) - checks if element is obscured by children - // or a top level container. - return (topLevelContainer == null || topLevelContainer.zIndex <= element.zIndex || - !obscuredByChildFeature || !obscuredByChildren(element, x, y)); - } - - - /** - * Determines whether an element is obscured by a child at a certain point on the screen. - * @param element The element that might be obscured by a child. - * @param x The x-coordinate of the point. - * @param y The y-coordiante of the point. - * @return True if a child element obscures the (parent) element at a certain point on the screen; False otherwise. - */ - private boolean obscuredByChildren(AtSpiElement element, double x, double y){ - - for(int i = 0; i < element.children.size(); i++){ - - AtSpiElement child = element.children.get(i); - - if(child.boundingBoxOnScreen != null && child.boundingBoxOnScreen.contains(x, y) && child.zIndex >= element.zIndex) { - return true; - } - - - } - - return false; - - } - - - //endregion - - - //region Serializable functionality - - - // Used to determine the class during serialization. - private static final long serialVersionUID = 456852951753L; - - - // Most likely used to serialize and deserialize an instance of this class - don't know if this is used by Testar though. - - - - /** - * Serialize an instance of this object. - * @param oos The outputstream to write to. - * @throws IOException An IO error occurred. - */ - private void writeObject(ObjectOutputStream oos) throws IOException { - oos.defaultWriteObject(); - } - - - /** - * Deserialize an instance of this object. - * @param ois The inputstream to write to. - * @throws IOException An IO error occurred. - * @throws ClassNotFoundException Class could not be found. - */ - private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException{ - ois.defaultReadObject(); - } - - - //endregion - - - //region Object overrides - - - @Override - public String toString() { - return "PID: " + pid + " - Running: " + isRunning + " - Active: " + isActive + " - Children: " + children.size(); - } - - - //endregion - - -} diff --git a/linux/src/org/testar/monkey/alayer/linux/AtSpiState.java b/linux/src/org/testar/monkey/alayer/linux/AtSpiState.java deleted file mode 100644 index ca1dfba5d..000000000 --- a/linux/src/org/testar/monkey/alayer/linux/AtSpiState.java +++ /dev/null @@ -1,130 +0,0 @@ -/*************************************************************************************************** -* -* Copyright (c) 2017 Open Universiteit - www.ou.nl -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, -* this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the copyright holder nor the names of its -* contributors may be used to endorse or promote products derived from -* this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -* POSSIBILITY OF SUCH DAMAGE. -*******************************************************************************************************/ - - -package org.testar.monkey.alayer.linux; - - -import org.testar.monkey.Util; -import org.testar.monkey.alayer.State; -import org.testar.monkey.alayer.Tags; -import org.testar.monkey.alayer.Widget; -import org.testar.monkey.alayer.WidgetIterator; - -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.util.Iterator; - - -/** - * Represents the state of an application - it is a wrapper around AT-SPI nodes of an application providing certain - * properties Testar uses to define state. - */ -public class AtSpiState extends AtSpiWidget implements State { - - - //region Constructors - - - /** - * Create the root of the State tree. - * @param root The AtSpiElement that is linked to the root. - */ - AtSpiState(AtSpiElement root) { - super(null, null, root); - this.root = this; - } - - - //endregion - - - //region Iterable iterator() { - return new WidgetIterator(this); - } - - - //endregion - - - //region Serializable functionality - - - // Used to determine the class during serialization. - private static final long serialVersionUID = 753654888555111999L; - - - // Most likely used to serialize and deserialize an instance of this class - don't know if this is used by Testar though. - - - - /** - * Serialize an instance of this object. - * @param oos The outputstream to write to. - * @throws IOException An IO error occurred. - */ - private void writeObject(ObjectOutputStream oos) throws IOException { - oos.defaultWriteObject(); - } - - - /** - * Deserialize an instance of this object. - * @param ois The inputstream to write to. - * @throws IOException An IO error occurred. - * @throws ClassNotFoundException Class could not be found. - */ - private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException{ - ois.defaultReadObject(); - } - - - //endregion - - - //region Object overrides - - - @Override - public String toString(){ return Util.treeDesc(this, 2, Tags.Role, Tags.Title); } - - - //endregion - - -} diff --git a/linux/src/org/testar/monkey/alayer/linux/AtSpiStateBuilder.java b/linux/src/org/testar/monkey/alayer/linux/AtSpiStateBuilder.java deleted file mode 100644 index f97d5491a..000000000 --- a/linux/src/org/testar/monkey/alayer/linux/AtSpiStateBuilder.java +++ /dev/null @@ -1,231 +0,0 @@ -/*************************************************************************************************** -* -* Copyright (c) 2017 Open Universiteit - www.ou.nl -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, -* this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the copyright holder nor the names of its -* contributors may be used to endorse or promote products derived from -* this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -* POSSIBILITY OF SUCH DAMAGE. -*******************************************************************************************************/ - - -package org.testar.monkey.alayer.linux; - - -import org.testar.monkey.Assert; -import org.testar.monkey.alayer.exceptions.StateBuildException; -import org.testar.monkey.alayer.linux.util.GdkHelper; -import org.testar.monkey.alayer.*; - -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.util.concurrent.*; - - -/** - * Represents an object that builds up a tree around AT-SPI elements that Testar uses to determine an application's state. - */ -public class AtSpiStateBuilder implements StateBuilder { - - - //region Global variables - - - private static final double _defaultTimeOut = 10; - private static final int _defaultThreadPoolCount = 1; - private static final double _secondsToMilliseconds = 1000.0; - - - private boolean _disposed = false; - - - //endregion - - - //region Properties - - - private final double _timeOut; - - - private transient ExecutorService _executorService; - - - //endregion - - - //region Constructors - - - /** - * Default constructor. - */ - public AtSpiStateBuilder() { this(_defaultTimeOut); } - - - /** - * Constructs a new state builder with a time out. - * @param timeOut The time after which a state request will time out in seconds. - */ - public AtSpiStateBuilder(double timeOut) { - - - Assert.isTrue(timeOut > 0); - this._timeOut = timeOut; - - - // Needed to be able to schedule asynchornous tasks conveniently. - _executorService = Executors.newFixedThreadPool(_defaultThreadPoolCount); - - - } - - - //endregion - - - //region StateBuilder implementation - - - /** - * Builds the current state tree for the supplied SUT. - * @param system The SUT for which to build the current state tree. - * @return The current state of the SUT. - * @throws StateBuildException Thrown when an error occurs with regards to concurrency. - */ - @Override - public State apply(SUT system) throws StateBuildException { - - - try { - Future future = _executorService.submit(new AtSpiStateFetcher(system)); - return future.get((long)(_timeOut * _secondsToMilliseconds), TimeUnit.MILLISECONDS); - } catch (InterruptedException | ExecutionException e) { - e.printStackTrace(); // by urueda - throw new StateBuildException(e); - } catch (TimeoutException e) { - - - // Create the default state - start with a default root element. - AtSpiRootElement atSpiRootElement = new AtSpiRootElement(); - atSpiRootElement.isRunning = system.isRunning(); - atSpiRootElement.timeStamp = System.currentTimeMillis(); - atSpiRootElement.hasStandardKeyboard = system.get(Tags.StandardKeyboard, null) != null; - atSpiRootElement.hasStandardMouse = system.get(Tags.StandardMouse, null) != null; - - - // Instead of the bounding box of the application use the screen bounding box - no clue why though. - atSpiRootElement.boundingBoxOnScreen = GdkHelper.getScreenBoundingBox(); - - - // Convert the root element to a State of an application. - AtSpiState defaultNotRespondingState = new AtSpiState(atSpiRootElement); - - - // Basically set the state manually to not responding. - defaultNotRespondingState.set(Tags.Role, Roles.Process); - defaultNotRespondingState.set(Tags.NotResponding, true); - - - return defaultNotRespondingState; - - - } - - - } - - - //endregion - - - //region Other needed functionality - - - /** - * Cleans up/ disposes of this instance - can be used if you don't want to rely on the GC to dispose of this object. - */ - public void dispose() { - - - // Only dispose of this object if it hasn't been disposed of before - NullPointerExceptions might happen otherwise. - if (_disposed) { - return; - } - - - // Stop concurrency. - _executorService.shutdown(); - _disposed = true; - - - } - - - /** - * Called by the Garbage Collector at some point to clean up this object. - */ - public void finalize() { - dispose(); - } - - - //endregion - - - //region Serializable functionality - - - // Used to determine the class during serialization. - private static final long serialVersionUID = 777888999111555444L; - - - // Most likely used to serialize and deserialize an instance of this class - don't know if this is used by Testar though. - - - - /** - * Serialize an instance of this object. - * @param oos The outputstream to write to. - * @throws IOException An IO error occurred. - */ - private void writeObject(ObjectOutputStream oos) throws IOException { - oos.defaultWriteObject(); - } - - - /** - * Deserialize an instance of this object. - * @param ois The inputstream to write to. - * @throws IOException An IO error occurred. - * @throws ClassNotFoundException Class could not be found. - */ - private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException{ - ois.defaultReadObject(); - } - - - //endregion - - -} diff --git a/linux/src/org/testar/monkey/alayer/linux/AtSpiStateFetcher.java b/linux/src/org/testar/monkey/alayer/linux/AtSpiStateFetcher.java deleted file mode 100644 index 3298a02f6..000000000 --- a/linux/src/org/testar/monkey/alayer/linux/AtSpiStateFetcher.java +++ /dev/null @@ -1,681 +0,0 @@ -/*************************************************************************************************** -* -* Copyright (c) 2017 Open Universiteit - www.ou.nl -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, -* this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the copyright holder nor the names of its -* contributors may be used to endorse or promote products derived from -* this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -* POSSIBILITY OF SUCH DAMAGE. -*******************************************************************************************************/ - - -package org.testar.monkey.alayer.linux; - - -import org.testar.monkey.Util; -import org.testar.monkey.alayer.linux.atspi.enums.AtSpiRoles; -import org.testar.monkey.alayer.linux.enums.AtSpiElementOrientations; -import org.testar.monkey.alayer.linux.util.GdkHelper; -import org.testar.monkey.alayer.*; -import org.testar.monkey.alayer.linux.atspi.*; - -import java.util.List; -import java.util.concurrent.Callable; - - -/** - * Represents an object that builds up a tree around AT-SPI elements and then converts it to a different State/ widget tree that Testar uses to determine an application's state. - */ -public class AtSpiStateFetcher implements Callable { - - - //region Global variables - - - private final SUT _system; - private static final int _retryCountFindSut = 5; - - - //endregion - - - //region Constructors - - - /** - * Creates a new instance of an object that retrieves the state of a supplied SUT. - * @param system The SUT to fetch the current state for. - */ - AtSpiStateFetcher(SUT system){ - this._system = system; - } - - - //endregion - - - //region Callable implementation - - - /** - * Creates the AtSpiState object for a SUT. - * This method will at some point (through concurrency service) be called by the AtSpiStateBuilder class (in apply method). - * @return The AtSpiState object for a SUT. - * @throws Exception A lot can go wrong... - */ - @Override - public AtSpiState call() throws Exception { - - - // Create an AT-SPI tree. - AtSpiRootElement rootOfAtSpiTree = buildAtSpiTree(); - - - // Convert the AT-SPI tree into a State (widget tree) that Testar wants to use. - AtSpiState widgetTree = createWidgetTree(rootOfAtSpiTree); - - - // Add some tags to the state tree - it describes a process and it is responding (most likely since - // we only queried AT-SPI and processed some data we didn't actually check any responsiveness). - widgetTree.set(Tags.Role, Roles.Process); - widgetTree.set(Tags.NotResponding, false); - - - // Give each widget in the tree a tag describing the path to find it. - for (Widget w : widgetTree) - w.set(Tags.Path, Util.indexString(w)); - - - return widgetTree; - - - } - - - //endregion - - - //region Helper methods - - - //region Testar's AT-SPI tree - - - /** - * Creates an AT-SPI tree by wrapping the wanted data in AtSpiElements. - * @return The root (AtSpiRootElement) of the AT-SPI tree. - */ - private AtSpiRootElement buildAtSpiTree() { - - - // Create the root of the tree and fill it with default values. - AtSpiRootElement atSpiRootElement = new AtSpiRootElement(); - atSpiRootElement.isRunning = _system.isRunning(); - atSpiRootElement.timeStamp = System.currentTimeMillis(); - atSpiRootElement.hasStandardKeyboard = _system.get(Tags.StandardKeyboard, null) != null; - atSpiRootElement.hasStandardMouse = _system.get(Tags.StandardMouse, null) != null; - - - // Instead of the bounding box of the application use the screen bounding box - no clue why though. - atSpiRootElement.boundingBoxOnScreen = GdkHelper.getScreenBoundingBox(); - - - if (!atSpiRootElement.isRunning) { - return atSpiRootElement; - } - - - // The application is running - get detailed information about it... - atSpiRootElement.pid = _system.get(Tags.PID); - atSpiRootElement.isActive = LinuxProcess.isActive(atSpiRootElement.pid); - - - // Get the AT-SPI application node. - String applicationName = _system.get(Tags.Desc).substring(_system.get(Tags.Desc).lastIndexOf("/") + 1); - AtSpiAccessible applicationNode = TreeWalker.findApplicationNode(applicationName, atSpiRootElement.pid); - int currentTry = 0; - - - if (applicationNode == null) { - - do { - - - currentTry += 1; - System.out.println("AT-SPI did not find the application with name: " + applicationName + "! Retrying, try " + currentTry + "/ " + _retryCountFindSut + "..."); - - - // Short pause to give the AT-SPI time to update. - try { - Thread.sleep(500); - } catch (InterruptedException e) { - e.printStackTrace(); - } - - - // Actual retry of the operation. - applicationNode = TreeWalker.findApplicationNode(applicationName, atSpiRootElement.pid); - - - } while (applicationNode == null && currentTry < _retryCountFindSut); - - - } - - - // If it's still null exit since no information can be queried from AT-SPI. - if (applicationNode == null) { - return atSpiRootElement; - } - - - // This time instead of screen use the actual application bounding box. - AtSpiRect appExtents = TreeWalker.getApplicationExtentsOnScreen(applicationNode); - atSpiRootElement.boundingBoxOnScreen = Rect.from(appExtents.x, appExtents.y, appExtents.width, appExtents.height); - - - // We need to create a tree of AT-SPI nodes (AtSpiAccessible) wrapped in the Testar specific AtSpiElement object. - // The Windows version queries Windows for every window and then uses the window handles to search for the - // corresponding element in the UIA tree - Linux systems cannot do this, therefore we only use the AT-SPI tree. - // Note: the Windows version determines multiple windows (for z-order) by querying windows for top level windows - // - the UIA tree will have those as separate nodes. Furthermore, messagebox windows (which are modal dialogs) - // show as child nodes of a window in the UIA tree. AT-SPI has multiple windows and modal windows as children of - // the application node. - - - // Create parent - child relations for the application node. - TreeWalker.createAccessibleTree(applicationNode, true); - - - // Retrieve the information Testar wants and wrap it in AtSpiElements. - wrapAtSpiNodes(applicationNode, atSpiRootElement); - - - // Modal dialog handling - needed to know which elements are blocked for interaction... - // If an application has modal windows then the other non-modal windows are blocked. - if (TreeWalker.hasApplicationModalDialogs(applicationNode)) { - - - // Find the non-modal dialog nodes. - List nonModalNodes = TreeWalker.getNonModalApplicationChildNodes(applicationNode); - - - // Find the AtSpiElement representing the node and mark it and its children blocked. - for (AtSpiAccessible a : nonModalNodes) { - - boolean markingSuccess = findAndMarkBlocked(a, atSpiRootElement); - - if (!markingSuccess) { - System.out.println("Could not find non-modal element '" + a.name() + "' and mark it and its children blocked."); - } - - } - - - // Find the modal dialog nodes. - List modalNodes = TreeWalker.getModalApplicationChildNodes(applicationNode); - - - // TODO: Because this stuff is undocumented, verify: the last modal element in an application's children is the modal node that blocks all other nodes (modal and non-modal). - modalNodes.remove(modalNodes.size() - 1); - - - // Find the AtSpiElement representing the node and mark it and its children blocked. - for (AtSpiAccessible a : modalNodes) { - - boolean markingSuccess = findAndMarkBlocked(a, atSpiRootElement); - - if (!markingSuccess) { - System.out.println("Could not find modal element '" + a.name() + " and mark it and its children blocked."); - } - - } - - - } - - - // z-index handling - needed to determine obscured elements - every window and its children - // should have a different z-index. - List windows = TreeWalker.getApplicationWindowNodes(applicationNode); - - for (int i = 0; i < windows.size(); i++) { - findAndSetZIndices(windows.get(i), atSpiRootElement, i + 1); - } - - - // Build a TopLevelContainer map for the root element. - createTopLevelContainerMap(atSpiRootElement, atSpiRootElement); - - - return atSpiRootElement; - - - } - - - /** - * Wraps an AtSpiAccessible node and its children. - * @param nodeToWrap The AtSpiAccessible node that will be wrapped. - * @param parentOfWrappingElement The parent of the AtSpiElement that will wrap the node. - */ - private void wrapAtSpiNodes(AtSpiAccessible nodeToWrap, AtSpiElement parentOfWrappingElement) { - - - // Process the current node and element. - AtSpiElement createdParent = createAndFillAtSpiElement(nodeToWrap, parentOfWrappingElement); - - - // Process childs of the node to wrap. - for (AtSpiAccessible a : nodeToWrap.children()) { - wrapAtSpiNodes(a, createdParent); - } - - - } - - - /** - * Creates and fills an AtSpiElement from an AtSpiAccessible node - also defines the parent AtSpiElement. - * @param node The node that will provide the information for the AtSpiElement. - * @param parent The parent AtSpiElement of the newly created AtSpiElement in Testar´ś own implementation of - * the AtSpi tree. - * @return Returns the newly created AtSpiElement. - */ - private AtSpiElement createAndFillAtSpiElement(AtSpiAccessible node, AtSpiElement parent) { - - - if (node == null || node.accessiblePtr() == 0) { - return null; - } - - - // Create new element and create the parent - child relations. - AtSpiElement nElement = new AtSpiElement(parent); - parent.children.add(nElement); - parent.root.pointerMap.put(nElement.accessiblePtr, nElement); - - - // Generic information. - // Notes: - // - HelpTest: not defined in AT-SPI - also used as ToolTipText in Testar, perhaps AT-SPI - // does have such property somewhere? - // - AutomationId: AT-SPI doesn´t use IDs to find elements - it uses pointers? - // - FrameworkId: called toolkit name in AT-SPI. - // - CtrlId: equal to the name of the Role enumeration in AT-SPI. - // - ClassName: perhaps under AtSpiAccessible's AtSpi-Relation?? - since it's not being - // used don't implement for now. - nElement.accessiblePtr = node.accessiblePtr(); - nElement.name = node.name(); - nElement.description = node.description(); - nElement.toolkitName = node.toolkitName(); - nElement.role = node.role(); - - if (node.component() != null) { - - // Use the location on the screen since Testar mimics the mouse to move to screen locations. - AtSpiRect bb = node.component().extentsOnScreen(); - - - // AT-SPI elements often contain negative width and height values for some reason. Testar cannot handle these - // values so make sure they're always non-negative. - nElement.boundingBoxOnScreen = Rect.from(bb.x, bb.y, (bb.width >= 0) ? bb.width : 0, (bb.height >= 0) ? bb.height : 0); - - - } else { - - // The element does not have visual component - mark it as non-interactable by setting the ignore property. - nElement.boundingBoxOnScreen = null; - nElement.ignore = true; - - } - - - // State information. - // Notes: - // - IsTopMost: AT-SPI does not support this and Linux only by sending X-events not as a property. - // - WindowVisualState: no clue what this is - never used on Windows so removed. - // - WindowInteractionState: not available in AT-SPI - only used to determine whether or not a - // - window (and it's children) is blocked or not - do a different block check. - AtSpiStateSet nodeStates = node.states(); - - if(nodeStates != null) { - - nElement.isEnabled = nodeStates.isEnabled(); - nElement.hasFocus = nodeStates.isFocused(); - nElement.isFocusable = nodeStates.isFocusable(); - nElement.isModal = nodeStates.isModal(); - - boolean h = nodeStates.isHorizontal(); - boolean v = nodeStates.isVertical(); - - - if (h && v) { - nElement.orientation = AtSpiElementOrientations.HorizontalAndVertical; - } else if (h) { - nElement.orientation = AtSpiElementOrientations.Horizontal; - } else if (v) { - nElement.orientation = AtSpiElementOrientations.Vertical; - } else { - nElement.orientation = AtSpiElementOrientations.Undefined; - } - - - } else { - // If the node doesn't have state information, then the node is most likely invalid. - nElement.ignore = true; - } - - - // Inferred information. - // Filter on ScrollBar nodes - they will have a (ControllerFor-) relationship with a ScrollPane or Viewport. - // However, relationships are hardly ever defined and no occurrences have been found of a ScrollBar, ScrollPane - // or Viewport having a relationship with whatever. - if (nElement.role == AtSpiRoles.ScrollBar) { - - nElement.canScroll = true; - - - // Get the values for the scrollbar to determine the percentage scrolled. - // Note: the viewPortSize should be percentage visible but since we don't know which element this - // scrollbar controls we can't get anything - use min and max of scrollbar itself. - AtSpiValue scrollBarValues = node.value(); - double current = 0; - double min = 0; - double max = 0; - double scrollPercentage = -1; - double viewPortSize = -1; - - - if (scrollBarValues != null) { - current = scrollBarValues.currentValue(); - min = scrollBarValues.minimumValue(); - max = scrollBarValues.maximumValue(); - } - - if (max != 0) { - scrollPercentage = current / (max - min); - viewPortSize = max - min; - } - - - if (nElement.orientation == AtSpiElementOrientations.Horizontal) { - - nElement.canScrollHorizontally = true; - nElement.hScrollPercentage = scrollPercentage; - nElement.vScrollPercentage = -1; - nElement.hScrollViewSizePercentage = viewPortSize; - nElement.vScrollViewSizePercentage = -1; - - } else if (nElement.orientation == AtSpiElementOrientations.Vertical) { - - nElement.canScrollVertically = true; - nElement.vScrollPercentage = scrollPercentage; - nElement.hScrollPercentage = -1; - nElement.vScrollViewSizePercentage = viewPortSize; - nElement.hScrollViewSizePercentage = -1; - - } - - } - - - // Infer from Role if the element is a toplevel container. - if (nElement.role == AtSpiRoles.Frame || nElement.role == AtSpiRoles.Menu || nElement.role == AtSpiRoles.MenuBar || - nElement.role == AtSpiRoles.Window || nElement.role == AtSpiRoles.Application || - nElement.role == AtSpiRoles.DocumentFrame) { - nElement.isTopLevelContainer = true; - } - - - return nElement; - - - } - - - /** - * Finds the AtSpiElement representing a certain node and marks it and its children as blocked. - * @param node The node for which to find the AtSpiElement. - * @param element An element of Testar's representation of the AT-SPI tree. - * @return True if found and marked; False otherwise. - */ - private boolean findAndMarkBlocked(AtSpiAccessible node, AtSpiElement element) { - - - // Check the current node. - if (node.accessiblePtr() == element.accessiblePtr) { - - // Mark blocked - exit after blocking since it will have marked all children as well. - markBlocked(element); - return true; - - } - - - // Current node is not the node we're looking for - check the child elements. - for (AtSpiElement e : element.children) { - - boolean result = findAndMarkBlocked(node, e); - - if (result) { - // Marked as blocked - we can stop searching. - return true; - } - - - } - - - return false; - - - } - - - /** - * Marks an element and its children as blocked. - * @param element The element and its children to mark blocked. - */ - private void markBlocked(AtSpiElement element) { - - // Process current element. - element.isBlocked = true; - - - // And its children. - for (AtSpiElement e : element.children) { - markBlocked(e); - } - - } - - - /** - * Finds the AtSpiElement representing a certain node and sets it and its children z-index. - * @param node The node for which to find the AtSpiElement. - * @param element An element of Testar's representation of the AT-SPI tree. - * @param zIndex The zIndex for this frame, dialog, window and its children. - * @return True if found and set; False otherwise. - */ - private boolean findAndSetZIndices(AtSpiAccessible node, AtSpiElement element, int zIndex) { - - - // Check the current node. - if (node.accessiblePtr() == element.accessiblePtr) { - - // Set z-indices - exit after since it will have set the z-index on all children as well. - setZIndex(element, zIndex); - return true; - - } - - - // Current node is not the node we're looking for - check the child elements. - for (AtSpiElement e : element.children) { - - boolean result = findAndSetZIndices(node, e, zIndex); - - if (result) { - // z-indices set - we can stop searching. - return true; - } - - - } - - - //System.out.println("Could not find frame, window, dialog element and set the z-index on it and its children."); - return false; - - - } - - - /** - * Sets the z-index on an element and its children. - * @param element The element and its children to set the z-index for. - * @param zIndex The z-index to use on the current element and its children. - */ - private void setZIndex(AtSpiElement element, int zIndex) { - - // Process current element. - element.zIndex = zIndex; - - - // And its children. - for (AtSpiElement e : element.children) { - setZIndex(e, zIndex); - } - - } - - - /** - * Creates a list of top level container elements and sorts the list. - * @param root The root of Testar's AT-SPI tree representation. - * @param element The current element to process. - */ - private void createTopLevelContainerMap(AtSpiRootElement root, AtSpiElement element) { - - - // Check if the current element is a top level container. - if (element.isTopLevelContainer) { - root.topLevelContainerMap.addElement(element); - } - - - // Process the children of the current element. - for (AtSpiElement e : element.children) { - createTopLevelContainerMap(root, e); - } - - - if (root.equals(element)) { - // This is the first method that got called and we're finished building the map - sort the elements. - root.topLevelContainerMap.sort(); - } - - - } - - - //endregion - - - //region Widget Tree - - - /** - * Creates a widget tree by creating widgets and linking them to AtSpiElements in the AtSpiTree. It also creates - * the parent - child relations in the widget tree. - * @param root The AtSpiRootElement to start the linking from. - * @return A State (widget tree) object. - */ - private AtSpiState createWidgetTree(AtSpiRootElement root){ - - - // Create a new AtSpiState (root of widget tree) and link it to the supplied AtSpiRootElement. - // The link in the AtSpiState is created on instantiation. - AtSpiState state = new AtSpiState(root); - root.backRef = state; - - - // Process each child of the AtSpiRootElement in the AT-SPI tree. - for(AtSpiElement childElement : root.children){ - if (!childElement.ignore) { - createWidgetTree(state, childElement); - } else { - - // The node should be ignored, but on Linux there will always be an Application node that needs to be - // ignored as first child - instead process its children. - if (childElement.role == AtSpiRoles.Application) { - for (AtSpiElement appChild : childElement.children) { - if (!appChild.ignore) { - createWidgetTree(state, appChild); - } - } - } - - } - - } - - - return state; - - - } - - - /** - * Creates a widget around the next AtSpiElement and links it as a widget child to a parent AtSpiWidget and - * creates the parent - child relation between widgets in the widget tree. - * @param parent The parent widget. - * @param element The AtSpiElement that will be the child of the AtSpiWidget parent. - */ - private void createWidgetTree(AtSpiWidget parent, AtSpiElement element){ - - - // Add the new AtSpiElement to the widget tree - it creates a new AtSpiWidget that links to the - // supplied AtSpiElement. - // The widget tree root is used to add the element because that way it can add a reference to itself to - // the newly created widget - this could also have been retrieved differently though... - AtSpiWidget w = parent.addChild(element); - element.backRef = w; - - - // Process each child of the AtSpiElement in the AT-SPI tree. - for(AtSpiElement child : element.children) { - createWidgetTree(w, child); - } - - - } - - - //endregion - - - //endregion - -} diff --git a/linux/src/org/testar/monkey/alayer/linux/AtSpiTags.java b/linux/src/org/testar/monkey/alayer/linux/AtSpiTags.java deleted file mode 100644 index 69f496f00..000000000 --- a/linux/src/org/testar/monkey/alayer/linux/AtSpiTags.java +++ /dev/null @@ -1,127 +0,0 @@ -/*************************************************************************************************** -* -* Copyright (c) 2017 Open Universiteit - www.ou.nl -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, -* this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the copyright holder nor the names of its -* contributors may be used to endorse or promote products derived from -* this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -* POSSIBILITY OF SUCH DAMAGE. -*******************************************************************************************************/ - - -package org.testar.monkey.alayer.linux; - -import org.testar.monkey.Util; -import org.testar.monkey.alayer.Tag; -import org.testar.monkey.alayer.linux.atspi.enums.AtSpiRoles; -import org.testar.monkey.alayer.linux.enums.AtSpiElementOrientations; - -import java.util.Collections; -import java.util.Set; - - -/** - * Creates and holds tags specific to AT-SPI info. - */ -public class AtSpiTags { - - - //region Global variables - - - private static final Set> _tagSet = Util.newHashSet(); - - - //endregion - - - //region Properties - Tags - - - // Notes: - // - Unused Windows tags have not been converted. - // - ControlType uses CtrlId which is equal to the Role enumeration id for AT-SPI. - // - FrameWorkId equals ToolkitName. - // - Not implemented in AT-SPI: - // + UIAClassName - // + UIAHelpText - // + UIAAutomationID - // + UIAWindowInteractionState - // + UIAWindowVisualState - - - // General info. - public static final Tag AtSpiName = from("AtSpiName", String.class); - public static final Tag AtSpiDescription = from("AtSpiDescription", String.class); - public static final Tag AtSpiRole = from("AtSpiRole", AtSpiRoles.class); - public static final Tag AtSpiOrientation = from("AtSpiOrientation", AtSpiElementOrientations.class); - public static final Tag AtSpiToolkitName = from("AtSpiToolkitName", String.class); - - - - // Scroll info. - public static final Tag AtSpiCanScroll = from("AtSpiCanScroll", Boolean.class); - public static final Tag AtSpiCanScrollHorizontally = from("AtSpiCanScrollHorizontally", Boolean.class); - public static final Tag AtSpiCanScrollVertically = from("AtSpiCanScrollVertically", Boolean.class); - public static final Tag AtSpiHorizontalScrollViewSizePercentage = from("AtSpiHorizontalScrollViewSizePercentage", Double.class); - public static final Tag AtSpiVerticalScrollViewSizePercentage = from("AtSpiVerticalScrollViewSizePercentage", Double.class); - public static final Tag AtSpiHorizontalScrollPercentage = from("AtSpiHorizontalScrollPercentage", Double.class); - public static final Tag AtSpiVerticalScrollPercentage = from("AtSpiVerticalScrollPercentage", Double.class); - - - // State info. - public static final Tag AtSpiIsModal = from("AtSpiIsModal", Boolean.class); - public static final Tag AtSpiHasFocus = from("AtSpiHasFocus", Boolean.class); - public static final Tag AtSpiIsFocusable = from("AtSpiIsFocusable", Boolean.class); - - - //endregion - - - //region Helper functions - - - /** - * Creates a new Tag with a name and type. - * @param name The name of the tag. - * @param valueType The type of the value associated with the tag. - * @param The type of the value associated with the tag. - * @return The created AtSpiTag. - */ - private static Tag from(String name, Class valueType){ - Tag ret = Tag.from(name, valueType); - _tagSet.add(ret); - return ret; - } - - - /** - * Returns the set of tags as an unmodifiable set. - * @return An unmodifiable set of the tags. - */ - public static Set> tagSet(){ return Collections.unmodifiableSet(_tagSet); } - - - //endregion - - -} diff --git a/linux/src/org/testar/monkey/alayer/linux/AtSpiWidget.java b/linux/src/org/testar/monkey/alayer/linux/AtSpiWidget.java deleted file mode 100644 index f184c5444..000000000 --- a/linux/src/org/testar/monkey/alayer/linux/AtSpiWidget.java +++ /dev/null @@ -1,723 +0,0 @@ -/*************************************************************************************************** -* -* Copyright (c) 2017 Open Universiteit - www.ou.nl -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, -* this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the copyright holder nor the names of its -* contributors may be used to endorse or promote products derived from -* this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -* POSSIBILITY OF SUCH DAMAGE. -*******************************************************************************************************/ - - -package org.testar.monkey.alayer.linux; - - -import org.testar.monkey.Assert; -import org.testar.monkey.Drag; -import org.testar.monkey.Util; -import org.testar.monkey.alayer.exceptions.NoSuchTagException; -import org.testar.monkey.alayer.*; - -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.io.Serializable; -import java.util.*; - - -/** - * Represents an element in an application - wraps properties of an AT-SPI node in a Testar defined way. - * - * A Widget is usually a control element of an SUT. - * Widgets have exactly one parent and can have several children. - * They are attached to a State and form a Widget Tree. - * In fact a State is a Widget itself and is the root - * of the Widget Tree. - * - */ -public class AtSpiWidget implements Widget, Serializable { - - - //region Properties - - - AtSpiState root; - public AtSpiWidget parent; - public AtSpiElement element; - - - private Map, Object> tags = Util.newHashMap(); - public ArrayList children = new ArrayList<>(); - - - //endregion - - - //region Constructors - - - /** - * Constructs a new AtSpiWidget with a root, parent and linked to an AtSpiElement. - * @param root The root of the State tree. - * @param parent The parent of the AtSpiWidget. - * @param element The element this AtSpiWidget links to. - */ - AtSpiWidget(AtSpiState root, AtSpiWidget parent, AtSpiElement element){ - - - this.parent = parent; - this.element = element; - this.root = root; - - - if(parent != null) { - parent.children.add(this); - } - - - } - - - //endregion - - - //region Widget implementation - - - /** - * Gets the root of the widget tree. - * @return The root of the widget tree. - */ - @Override - public AtSpiState root() { - return root; - } - - - /** - * Gets the parent of the widget tree. - * @return The parent of the widget tree. - */ - @Override - public Widget parent() { - return parent; - } - - - /** - * Returns the child by index. - * @param i The index of the child. - * @return The child at index i. - */ - @Override - public Widget child(int i) { - return children.get(i); - } - - - /** - * Adds a child to widget - Method is never used. - * @return The widget that got added. - */ - @Override - public Widget addChild() { - return new AtSpiWidget(root, this, null); - } - - - //region Other necessary functionality - - - /** - * Adds a new widget to the State (widget tree) as a child of this widget. - * @param element The AtSpiElement that will be linked to the new AtSpiWidget. - * @return The newly created AtSpiWidget that's linked with the AtSpiElement. - */ - AtSpiWidget addChild(AtSpiElement element){ - return new AtSpiWidget(root, this, element); - } - - - //endregion - - - /** - * Gets the number of children. - * @return The number of children. - */ - @Override - public int childCount() { - return children.size(); - } - - - /** - * Removes the widget and its children from the State tree - it resets the connections to null. - */ - @Override - public void remove() { - - Assert.isTrue(this != root, "You cannot remove the root!"); - assert(parent != null); - parent.children.remove(this); - - invalidate(this); - - } - - - /** - * Sets this widget to be a child of the supplied widget. - * @param p The new parent widget of this widget. - * @param idx The index at which this widget will be added as a child. - */ - @Override - public void moveTo(Widget p, int idx) { - - Assert.notNull(p); - Assert.isTrue(p instanceof AtSpiWidget); - Assert.isTrue(this != root, "You cannot set the root's parent!"); - assert(parent != null); - - - AtSpiWidget atSpiParent = (AtSpiWidget) p; - Assert.isTrue(atSpiParent.root == root); - Assert.isTrue(!Util.isAncestorOf(this, p), "The parent is a descendent of this widget!"); - - - // Set this widget to the child of the supplied widget. - parent.children.remove(this); - atSpiParent.children.add(idx, this); - parent = atSpiParent; - - } - - - /** - * Creates an array of drag points - ?points where can be clicked and then the element will scroll?. - * @param scrollArrowSize The size of scrolling arrows. - * @param scrollThick The scroller thickness. - * @return An array of drag points. - */ - @SuppressWarnings("Duplicates") - @Override - public Drag[] scrollDrags(double scrollArrowSize, double scrollThick) { - - - boolean hasScroll = get(AtSpiTags.AtSpiCanScroll, null); - if (!hasScroll) { - return null; - } - - - Drag[] hDrags = null, vDrags = null; - - - boolean hScroll = get(AtSpiTags.AtSpiCanScrollHorizontally, Boolean.FALSE); - if (hScroll){ - - double hViewSize = get(AtSpiTags.AtSpiHorizontalScrollViewSizePercentage, Double.MIN_VALUE); - - if (hViewSize > 0){ - - double hScrollPercent = get(AtSpiTags.AtSpiHorizontalScrollPercentage, -1.0); - Shape shape = get(Tags.Shape, null); - - if (shape != null){ - hDrags = getDrags(shape,true, hViewSize, hScrollPercent, scrollArrowSize, scrollThick); - } - - } - - } - - - boolean vScroll = get(AtSpiTags.AtSpiCanScrollVertically, Boolean.FALSE); - if (vScroll){ - - double vViewSize = get(AtSpiTags.AtSpiVerticalScrollViewSizePercentage, Double.MIN_VALUE); - - if (vViewSize > 0){ - - double vScrollPercent = get(AtSpiTags.AtSpiVerticalScrollPercentage, -1.0); - Shape shape = get(Tags.Shape, null); - - if (shape != null){ - vDrags = getDrags(shape,false, vViewSize, vScrollPercent, scrollArrowSize, scrollThick); - } - - } - } - - - return Util.join(hDrags,vDrags); - - - } - - - /** - * Creates a string representation for the widget. - * @param tab The TAB string to use - to be able to define different spacings most likely. - * @return Returns a string representation for the widget. - */ - @Override - public String getRepresentation(String tab) { - - return (tab + "WIDGET = CONCRETE_" + this.get(Tags.ConcreteID) + " ABSTRACT(R)_" + this.get(Tags.Abstract_R_ID) + - " ABSTRACT(R,T)_" + this.get(Tags.Abstract_R_T_ID) + " ABSTRACT(R,T,P)_" + this.get(Tags.Abstract_R_T_P_ID) + "\n") + - getPropertiesRepresentation(tab); - - } - - - /** - * Creates a string representation of the AtSpiWidget. - * @param tags The tags to include in the string representation. - * @return A String representation of the AtSpiWidget. - */ - @Override - public String toString(Tag... tags) { - return Util.widgetDesc(this, tags); - } - - - //region Widget Helper functions - - - /** - * Disconnects a widget and its children from the State tree. - * @param w The widget to disconnect. - */ - private void invalidate(AtSpiWidget w){ - - - // Reset the connection for the current widget. - if(w.element != null) { - w.element.backRef = null; - } - w.root = null; - - - // Also reset the connections for its children. - for(AtSpiWidget c : w.children) { - invalidate(c); - } - - - } - - - /** - * Creates a string representation for the widget. - * @param tab The TAB string to use - to be able to define different spacings most likely. - * @return Returns a string representation for the widget. - */ - @SuppressWarnings("StringConcatenationInsideStringBufferAppend") - private String getPropertiesRepresentation(String tab){ - - - StringBuilder pr = new StringBuilder(); - - - Role role = this.get(Tags.Role, null); - if (role != null) { - pr.append(tab + "ROLE = " + role.toString() + "\n"); - } - - - - String title = this.get(Tags.Title, null); - if (title != null) { - pr.append(tab + "TITLE = " + title + "\n"); - } - - - - Shape shape = this.get(Tags.Shape, null); - if (shape != null) { - pr.append(tab + "SHAPE = " + shape.toString() + "\n"); - } - - - - pr.append(tab + "CHILDREN = " + this.childCount() + "\n"); - pr.append(tab + "PATH = " + this.get(Tags.Path) + "\n"); - - - return pr.toString(); - - - } - - - /** - * Gets drag points depending on orientation and certain scroll properties. - * @param shape Shape of the scrollable element?? - * @param scrollOrientation True = horizontal, False = vertical. - * @param viewSize Viewport percentage shown. - * @param scrollPercent Percentage scrolled. - * @param scrollArrowSize Size of the arrow. - * @param scrollThick Size of the scroll thumb. - * @return An array of drag points. - */ - @SuppressWarnings("Duplicates") - private Drag[] getDrags(Shape shape, boolean scrollOrientation, double viewSize, double scrollPercent, - double scrollArrowSize, double scrollThick) { - - double scrollableSize = (scrollOrientation ? shape.width() : shape.height()) - scrollArrowSize * 2; - double fixedH, fixedV; - - if (scrollOrientation){ - - // Horizontal. - fixedH = shape.x() + scrollArrowSize + - scrollableSize*scrollPercent/100.0 + - (scrollPercent < 50.0 ? scrollThick/2 : -3*scrollThick/2); - fixedV = shape.y() + shape.height() - scrollThick/2; - - } else { - - // Vertical. - fixedH = shape.x() + shape.width() - scrollThick/2; - fixedV = shape.y() + scrollArrowSize + - scrollableSize*scrollPercent/100.0 + - (scrollPercent < 50.0 ? scrollThick/2 : -3*scrollThick/2); - - } - - - int dragC = (int)Math.ceil(100.0 / viewSize) - 1; - if (dragC < 1) { - return null; - } - - - double[] emptyDragPoints = calculateScrollDragPoints(dragC, - scrollOrientation ? fixedH-shape.x() : fixedV-shape.y(), - scrollableSize/(double)dragC); - - - Drag[] drags = new Drag[dragC]; - for (int i=0; i The type of the value associated with the tag. - * @return The value associated with the tag. - * @throws NoSuchTagException When the tag could not be found. - */ - @Override - public T get(Tag tag) throws NoSuchTagException { - - T ret = get(tag, null); - - if(ret == null) { - throw new NoSuchTagException(tag); - } - - return ret; - - } - - - /** - * Retrieves the value associated with a tag from this AtSpiWidget. - * @param tag Tag to retrieve. - * @param The type of the value associated with the tag. - * @param defaultValue Default value which will be returned if the tag cannot be found. - * @return The value associated with the tag. - */ - @Override - public T get(Tag tag, T defaultValue) { - - - // Check if the value for the tag is cached. - Object ret = tags.get(tag); - - - // Cached - return value. - // No element to retrieve the value from or non-existing tag - return default value. - if(ret != null){ - //noinspection unchecked - return (T)ret; - }else if(element == null || tags.containsKey(tag)){ - return defaultValue; - } - - - // Retrieve the value for the tag by returning the value from the linked AtSpiElement. - // Notes: - // - Not implemented in AT-SPI: - // + ToolTipText - // + UIAWindowInteractionState - // + UIAWindowVisualState - // + UIAAutomationId - // + UIAHelpText - // + UIAClassName - // - UIAControlType = AtSpiRole. - if(tag.equals(Tags.Desc)){ - ret = element.name; - }else if(tag.equals(Tags.Role)){ - ret = AtSpiRolesWrapper.fromTypeId(element.role.ordinal()); - }else if(tag.equals(Tags.HitTester)){ - ret = new AtSpiHitTester(element); - }else if(tag.equals(Tags.Shape)){ - ret = element.boundingBoxOnScreen; - }else if(tag.equals(Tags.Blocked)){ - ret = element.isBlocked; - }else if(tag.equals(Tags.Enabled)){ - ret = element.isEnabled; - }else if(tag.equals(Tags.Title)){ - ret = element.name; - }else if(tag.equals(Tags.PID)){ - ret = this == root ? ((AtSpiRootElement)element).pid : null; - }else if(tag.equals(Tags.IsRunning)){ - ret = this == root ? ((AtSpiRootElement)element).isRunning : null; - }else if(tag.equals(Tags.TimeStamp)){ - ret = this == root ? ((AtSpiRootElement)element).timeStamp : null; - }else if(tag.equals(Tags.Foreground)){ - ret = this == root ? ((AtSpiRootElement)element).isActive : null; - }else if(tag.equals(Tags.HasStandardKeyboard)){ - ret = this == root ? ((AtSpiRootElement)element).hasStandardKeyboard : null; - }else if(tag.equals(Tags.HasStandardMouse)){ - ret = this == root ? ((AtSpiRootElement)element).hasStandardMouse : null; - }else if(tag.equals(AtSpiTags.AtSpiName)){ - ret = element.name; - }else if(tag.equals(AtSpiTags.AtSpiOrientation)){ - ret = element.orientation; - }else if(tag.equals(Tags.ZIndex)){ - ret = element.zIndex; - }else if(tag.equals(AtSpiTags.AtSpiIsModal)){ - ret = element.isModal; - }else if(tag.equals(AtSpiTags.AtSpiCanScroll)){ - ret = element.canScroll; - }else if(tag.equals(AtSpiTags.AtSpiCanScrollHorizontally)){ - ret = element.canScrollHorizontally; - }else if(tag.equals(AtSpiTags.AtSpiCanScrollVertically)){ - ret = element.canScrollVertically; - }else if(tag.equals(AtSpiTags.AtSpiHorizontalScrollViewSizePercentage)){ - ret = element.hScrollViewSizePercentage; - }else if(tag.equals(AtSpiTags.AtSpiVerticalScrollViewSizePercentage)){ - ret = element.vScrollViewSizePercentage; - }else if(tag.equals(AtSpiTags.AtSpiHorizontalScrollPercentage)){ - ret = element.hScrollPercentage; - }else if(tag.equals(AtSpiTags.AtSpiVerticalScrollPercentage)){ - ret = element.vScrollPercentage; - }else if(tag.equals(AtSpiTags.AtSpiRole)){ - ret = element.role; - }else if(tag.equals(AtSpiTags.AtSpiToolkitName)){ - ret = element.toolkitName; - }else if(tag.equals(AtSpiTags.AtSpiHasFocus)){ - ret = element.hasFocus; - }else if(tag.equals(AtSpiTags.AtSpiIsFocusable)){ - ret = element.isFocusable; - }else if(tag.equals(AtSpiTags.AtSpiDescription)){ - ret = element.description; - } - - - // Cache the value for a next time. - tags.put(tag, ret); - - - //noinspection unchecked - return (ret == null) ? defaultValue : (T)ret; - - - } - - - /** - * Gets an iterator for the tags of this widget. - * @return An iterator to iterate over the tags of this widget. - */ - @Override - public Iterable> tags() { - - - final AtSpiWidget self = this; - Assert.notNull(self); - - final Set> queryTags = new HashSet<>(); - queryTags.addAll(tags.keySet()); - queryTags.addAll(Tags.tagSet()); - queryTags.addAll(AtSpiTags.tagSet()); - - - return () -> new Iterator>(){ - Iterator> i = queryTags.iterator(); - AtSpiWidget target = self; - Tag next; - - - @SuppressWarnings("Duplicates") - private Tag fetchNext(){ - if(next == null){ - while(i.hasNext()){ - next = i.next(); - if(target.get(next, null) != null) - return next; - } - next = null; - } - return next; - } - - - public boolean hasNext() { - return fetchNext() != null; - } - - - public Tag next() { - Tag ret1 = fetchNext(); - if(ret1 == null) - throw new NoSuchElementException(); - next = null; - return ret1; - } - - - public void remove() { throw new UnsupportedOperationException(); } - - - }; - - } - - - /** - * Sets the value for the supplied tag. - * @param tag Tag to set/ associate the value for/ with. - * @param value The value to associate with the tag. - * @param The type of the value. - */ - @Override - public void set(Tag tag, T value) { - Assert.notNull(tag, value); - tags.put(tag, value); - } - - - /** - * Clears the value of the tag - it does not actually remove the Tag object from the Map. - * @param tag Tag to clear the value for. - */ - @Override - public void remove(Tag tag) { - Assert.notNull(tag); - tags.put(tag, null); - } - - - //endregion - - - //region Serializable functionality - - - // Used to determine the class during serialization. - private static final long serialVersionUID = 456999777888222L; - - - // Most likely used to serialize and deserialize an instance of this class - don't know if this is used by Testar though. - - - - /** - * Serialize an instance of this object. - * @param oos The outputstream to write to. - * @throws IOException An IO error occurred. - */ - private void writeObject(ObjectOutputStream oos) throws IOException { - oos.defaultWriteObject(); - } - - - /** - * Deserialize an instance of this object. - * @param ois The inputstream to write to. - * @throws IOException An IO error occurred. - * @throws ClassNotFoundException Class could not be found. - */ - private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException{ - ois.defaultReadObject(); - } - - - //endregion - - -} diff --git a/linux/src/org/testar/monkey/alayer/linux/GdkScreenCanvas.java b/linux/src/org/testar/monkey/alayer/linux/GdkScreenCanvas.java deleted file mode 100644 index 45582f39d..000000000 --- a/linux/src/org/testar/monkey/alayer/linux/GdkScreenCanvas.java +++ /dev/null @@ -1,136 +0,0 @@ -/*************************************************************************************************** -* -* Copyright (c) 2017 - 2025 Open Universiteit - www.ou.nl -* Copyright (c) 2017 - 2025 Universitat Politecnica de Valencia - www.upv.es -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, -* this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the copyright holder nor the names of its -* contributors may be used to endorse or promote products derived from -* this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -* POSSIBILITY OF SUCH DAMAGE. -*******************************************************************************************************/ - - -package org.testar.monkey.alayer.linux; - -import org.testar.monkey.Pair; -import org.testar.monkey.alayer.Canvas; -import org.testar.monkey.alayer.Pen; - - -/** - * Represents a canvas for a linux screen on which can be painted. - */ -public class GdkScreenCanvas implements Canvas { - - - //region Canvas implementation - - - @Override - public double width() { - return 0; - } - - @Override - public double height() { - return 0; - } - - @Override - public double x() { - return 0; - } - - @Override - public double y() { - return 0; - } - - @Override - public void begin() { - - } - - @Override - public void end() { - - } - - @Override - public void line(Pen pen, double x1, double y1, double x2, double y2) { - - } - - @Override - public void text(Pen pen, double x, double y, double angle, String text) { - - } - - @Override - public Pair textMetrics(Pen pen, String text) { - return null; - } - - @Override - public void clear(double x, double y, double width, double height) { - - } - - @Override - public void triangle(Pen pen, double x1, double y1, double x2, double y2, double x3, double y3) { - - } - - @Override - public void image(Pen pen, double x, double y, double width, double height, int[] image, int imageWidth, int imageHeight) { - - } - - @Override - public void ellipse(Pen pen, double x, double y, double width, double height) { - - } - - @Override - public void rect(Pen pen, double x, double y, double width, double height) { - - } - - @Override - public Pen defaultPen() { - return null; - } - - @Override - public void release() { - - } - - @Override - public void paintBatch() { - - } - - //endregion - - -} diff --git a/linux/src/org/testar/monkey/alayer/linux/LinuxProcess.java b/linux/src/org/testar/monkey/alayer/linux/LinuxProcess.java deleted file mode 100644 index c5c0d3d1d..000000000 --- a/linux/src/org/testar/monkey/alayer/linux/LinuxProcess.java +++ /dev/null @@ -1,864 +0,0 @@ -/*************************************************************************************************** -* -* Copyright (c) 2017 Open Universiteit - www.ou.nl -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, -* this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the copyright holder nor the names of its -* contributors may be used to endorse or promote products derived from -* this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -* POSSIBILITY OF SUCH DAMAGE. -*******************************************************************************************************/ - - -package org.testar.monkey.alayer.linux; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.lang.reflect.Field; -import java.util.ArrayList; -import java.util.List; -import java.util.Set; - -import org.testar.monkey.Assert; -import org.testar.monkey.Util; -import org.testar.monkey.alayer.SUT; -import org.testar.monkey.alayer.SUTBase; -import org.testar.monkey.alayer.Tag; -import org.testar.monkey.alayer.Tags; -import org.testar.monkey.alayer.devices.AWTKeyboard; -import org.testar.monkey.alayer.devices.AWTMouse; -import org.testar.monkey.alayer.devices.Keyboard; -import org.testar.monkey.alayer.devices.Mouse; -import org.testar.monkey.alayer.exceptions.FruitException; -import org.testar.monkey.alayer.exceptions.SystemStartException; -import org.testar.monkey.alayer.exceptions.SystemStopException; -import org.testar.monkey.alayer.linux.atspi.AtSpiAccessible; -import org.testar.monkey.alayer.linux.atspi.TreeWalker; -import org.testar.monkey.alayer.linux.util.JavaHelper; -import org.testar.monkey.alayer.linux.util.xdotools; - -/** - * Represents a Linux process. - */ -public class LinuxProcess extends SUTBase { - - - //region Global variables - - - private static final String Command_AllProcesses = "ps -axo pid,pcpu,size,comm"; - private static final String Command_KillProcess = "kill %1$d"; - private static final String Command_FindProcess = "ps -p %1$d -o pid,pcpu,size,comm"; - private static final String Command_FindProcessName = "ps -p %1$d -o pid,cmd"; - - - private static final String EmptyString = ""; - - - private static final int PidIndex = 0; - private static final int CpuIndex = 1; - private static final int SizeIndex = 2; - private static final int ProcessNameIndex = 1; - - private static final int ProcessInfoNameLength = 2; - private static final int ProcessInfoLength = 4; - - - private Process _process; - - - private final Keyboard _kbd = AWTKeyboard.build(); - private final Mouse _mouse = AWTMouse.build(); - - - //endregion - - - //region Properties - - - private long _pid; - - - /** - * Gets the PID of the Linux process. - * @return The PID of the Linux process. - */ - public long get_pid() { - return _pid; - } - - - //endregion - - - //region Constructors - - - /** - * Private constructor. - * @param p the encapsulating Linux process. - */ - private LinuxProcess(Process p) { - _process = p; - retrievePid(p); - } - - - /** - * Creates a Linux process from a PID. - * @param pid The PID of the Linux process. - */ - private LinuxProcess(long pid) { - _pid = pid; - } - - - //endregion - - - //region Other needed functionality - - - /** - * Retrieves a LinuxProcess instance from a path. - * @param path path to a Linux application. - * @return a LinuxProcess instance. - * @throws SystemStartException If the application cannot be launched. - */ - public static LinuxProcess fromExecutable(String path) throws SystemStartException { - - try{ - - Assert.notNull(path); - - try { - - Process p = Runtime.getRuntime().exec(path); - LinuxProcess lp = new LinuxProcess(p); - - // Set the description to the path. - lp.set(Tags.Desc, path); - - return lp; - - } catch (IOException e) { - throw new SystemStartException(new FruitException(e.getMessage())); - } - - }catch(FruitException fe){ - throw new SystemStartException(fe); - } - - } - - - /** - * Retrieves a list of available running SUT processes on this machine. - * @return A list of available SUTs currently running on this machine. - */ - public static List fromAll() { - - - List suts = new ArrayList<>(); - - - // Get a list of all running processes on this Unix machine by using a terminal command and parsing the output. - List processInfos = runProcessCommand(Command_AllProcesses); - - - if (processInfos == null) { - return null; - } - - - for(String[] pi : processInfos) { - - LinuxProcess lp = parseProcess(pi); - - if (lp != null){ - suts.add(lp); - } - - } - - - // The calling code expects null when the list is empty. - if (suts.isEmpty()) { - return null; - } - - - return suts; - - - } - - - /** - * Determines whether the Linux process is active/ in the foreground. - * @return True if the process's window is currently active/ in the foreground; False otherwise. - */ - public boolean isActive() { - return isActive(this); - } - - - /** - * Determines whether the Linux process is active/ in the foreground. - * @param pid The PID of the Linux process which to check the active state for. - * @return True if the process's window is currently active/ in the foreground; False otherwise. - */ - public static boolean isActive(long pid) { - return isActive(fromPid(pid)); - } - - - /** - * Determines whether the Linux process is active/ in the foreground. - * @param lp The Linux process which to check the active state for. - * @return True if the process's window is currently active/ in the foreground; False otherwise. - */ - public static boolean isActive(LinuxProcess lp) { - - if (lp == null) { - return false; - } else if (!lp.isRunning()) { - return false; - } - - return xdotools.getPIDFromActiveWindow() == lp.get_pid(); - - } - - - /** - * Tries to activate/ bring to the foreground the window associated with this Linux process. - * @return True if the process's window got activated/ moved to the foreground successfully; False otherwise. - */ - public boolean activate() { - return activate(this); - } - - - /** - * Tries to activate/ bring to the foreground the window associated with the Linux process that hold the specified PID. - * @param pid The PID of the Linux process of which the window needs to be activated/ brought to the foreground. - * @return True if the process's window got activated/ moved to the foreground successfully; False otherwise. - */ - public static boolean activate(long pid) { - return activate(fromPid(pid)); - } - - - /** - * Tries to activate/ bring to the foreground the window associated with the supplied Linux process. - * @param lp The Linux process of which the window needs to be activated/ brought to the foreground. - * @return True if the process's window got activated/ moved to the foreground successfully; False otherwise. - */ - public static boolean activate(LinuxProcess lp) { - - - if (lp == null) { - return false; - } else if (!lp.isRunning()) { - return false; - } - - - // Assumptions: - // - There are window manager on unix systems that don't support Alt+Tab to switch application windows. - // - Active window is the same as foreground window on Unix systems. - // - The name of the application is in the LinuxProcess's description which should contain the filepath. - - - // No need to activate if it's already the active window. - if (lp.isActive()) { - return true; - } - - - // To activate the application through AT-SPI we need to know the application's name. - String applicationName = lp.get(Tags.Desc).substring(lp.get(Tags.Desc).lastIndexOf("/") + 1); - - - // There may be multiple instances of the same application running - therefore a list is returned with - // application nodes with the same name. - List applicationNodes = TreeWalker.getApplicationNodes(applicationName); - - - if (applicationNodes.size() == 0) { - System.out.println("Could not find any applications with the name '" + applicationName + "'."); - return false; - } - - - // Activate each application through AT-SPI and find the PID for each active application through xdotool. - // Once verified that the node activated the instance of the application launched by us - stop. - for (AtSpiAccessible application : applicationNodes) { - - - // Activate application. - if (TreeWalker.activateApplication(application)) { - - // Short pause to give the application time to activate. - try { - Thread.sleep(200); - } catch (InterruptedException e) { - e.printStackTrace(); - } - - - // Retrieve PID through xdotool. - int pid = xdotools.getPIDFromActiveWindow(); - - - // Check if the PID matches the PID of the process we're supposed to activate. - if (pid == lp.get_pid()) { - return true; - } - - - } else { - System.out.println("Cannot activate an application with the same name - continuing loop..."); - } - - - } - - - // Could not find or activate the application we launched. - System.out.println("Could not find or activate the application!"); - return false; - - - } - - - /** - * Retrieves the memory usage for a given Linux process. - * @param lp The Linux process to retrieve the memory usage for. - * @return The memory the Linux process uses; 0 otherwise. - */ - public static long getMemUsage(LinuxProcess lp){ - - - if (!lp.isRunning()){ - System.out.println("SUT is not running - cannot retrieve RAM usage!"); - return 0; - } - - - List processInfos = runProcessCommand(String.format(Command_FindProcess, lp.get_pid())); - - - if (processInfos == null || processInfos.isEmpty()) { - System.out.println("Running command to find process info failed - cannot retrieve RAM usage!"); - return 0; - } - - - // Lets assume that it could happen that multiple lines are returned - parse and find the requested PID. - for(String[] pi : processInfos) { - - LinuxProcess lpe = parseProcess(pi); - - if (lpe != null && lpe.get_pid() == lp.get_pid()){ - - // Parse the current processInfo and extract the memory usage. - if (JavaHelper.tryParseInt(pi[SizeIndex])) { - return Integer.parseInt(pi[SizeIndex]); - } else { - System.out.println("Could not parse the process info - cannot retrieve RAM usage!"); - return 0; - } - - - } - - } - - System.out.println("Could not find the process info - cannot retrieve RAM usage!"); - return 0; - - - } - - - /** - * Retrieves the cpu usage for a given Linux process. - * @param lp The Linux process to retrieve the cpu usage for. - * @return The cpu the Linux process uses; 0 otherwise. - */ - public static double getCpuUsage(LinuxProcess lp){ - - - if (!lp.isRunning()){ - System.out.println("SUT is not running - cannot retrieve CPU usage!"); - return 0; - } - - - List processInfos = runProcessCommand(String.format(Command_FindProcess, lp.get_pid())); - - - if (processInfos == null || processInfos.isEmpty()) { - System.out.println("Running command to find process info failed - cannot retrieve CPU usage!"); - return 0; - } - - - // Lets assume that it could happen that multiple lines are returned - parse and find the requested PID. - for(String[] pi : processInfos) { - - LinuxProcess lpe = parseProcess(pi); - - if (lpe != null && lpe.get_pid() == lp.get_pid()){ - - // Parse the current processInfo and extract the cpu usage. - if (JavaHelper.tryParseDouble(pi[CpuIndex])) { - return Double.parseDouble(pi[CpuIndex]); - } else { - System.out.println("Could not parse the process info - cannot retrieve CPU usage!"); - return 0; - } - - - } - - } - - System.out.println("Could not find the process info - cannot retrieve CPU usage!"); - return 0; - - - } - - - /** - * Creates a Linux process from a PID. - * @param pid The PID of a Linux process. - * @return LinuxProcess instance representing the Linux process with the given PID. - */ - public static LinuxProcess fromPid(long pid) { - - // Create a LinuxProcess instance from PID. - LinuxProcess lp = new LinuxProcess(pid); - - // Set a different description tag on the instance - process name + PID. - lp.set(Tags.Desc, getProcessName(pid) + " (PID: " + pid + ")"); - - return lp; - - } - - - /** - * Gets a name for the Linux process. - * @return The name of the Linux process. - */ - public String getProcessName() { - return getProcessName(_pid); - } - - - /** - * Most likely called when garbage collected. - */ - public void finalize() { - // Apparently finalize is called even though the object is still referenced. - //stop(); - } - - - //endregion - - - //region Helper functions - - - /** - * Retrieve the PID on unix/linux systems - * @param p the process to retrive the PID from. - */ - private void retrievePid(Process p) { - - - if(p.getClass().getName().equals("java.lang.UNIXProcess")) { - - try { - Field f = p.getClass().getDeclaredField("pid"); - f.setAccessible(true); - _pid = f.getInt(p); - } catch (Throwable e) { - throw new FruitException(e.getMessage()); - } - - } - - - } - - - /** - * Parses a process info String array into a Linux Process. - * @param processInfo The info of a Linux process as a String array. - * @return A Linux process instance. - */ - private static LinuxProcess parseProcess(String[] processInfo) { - - - if (processInfo.length != ProcessInfoLength) { - // Missing process info - can't be certain to parse correctly. - return null; - } - - - if (!JavaHelper.tryParseInt(processInfo[PidIndex])) { - // Can't parse the first entry as the PID. - return null; - } - - - int pid = Integer.parseInt(processInfo[PidIndex]); - - - if (pid <= 0) { - //Invalid PID. - return null; - } - return new LinuxProcess(pid); - - - } - - - /** - * Runs a (process) command and returns the received process infos as a String array. - * @param command the command to run. - * @return List of String arrays containing info on the processes. - */ - private static List runProcessCommand(String command) { - - - ArrayList processInfos = new ArrayList<>(); - - try { - - - // Run the command. - Process p = Runtime.getRuntime().exec(command); - - - // Get the stream to read the command output from. - BufferedReader commandOutputReader = new BufferedReader(new InputStreamReader(p.getInputStream())); - - - // Read the output as lines - omit the first (header) line. - String processLine = commandOutputReader.readLine(); - - if (processLine != null) { - while ((processLine = commandOutputReader.readLine()) != null) { - - - // Remove duplicate whitespace and remove leading and trailing whitespace. - processLine = processLine.replaceAll("\\s+", " "); - processLine = processLine.trim(); - - // Split the processes in their info parts. - String[] processInfo = processLine.split(" "); - - processInfos.add(processInfo); - - - } - } - return processInfos; - - - } catch (IOException e) { - // Can ignore the error - return null. - return null; - } - - } - - - /** - * Creates a list of running Linux processes in a different kind of representation. - * @return A list of Linux process representations of type LinuxProcessHandle. - */ - private static List runningProcesses(){ - - - // Retrieve a list of LinuxProcesses. - List linuxProcesses = fromAll(); - List linuxProcessHandles = new ArrayList<>(); - - - if (linuxProcesses == null) { - return linuxProcessHandles; - } - - - // Convert the list to a list of LinuxProcessHandles. - for (SUT lp : linuxProcesses) { - linuxProcessHandles.add(new LinuxProcessHandle((LinuxProcess)lp)); - } - - - return linuxProcessHandles; - - - } - - - /** - * Gets a name for the Linux process. - * @param pid The PID of the Linux process to get the name from. - * @return The name of the Linux process. - */ - private static String getProcessName(long pid) { - - - ArrayList processInfos = new ArrayList<>(); - - - try { - - - // Run the command - Process p = Runtime.getRuntime().exec(String.format(Command_FindProcessName, pid)); - - - // Get the stream to read the command output from. - BufferedReader commandOutputReader = new BufferedReader(new InputStreamReader(p.getInputStream())); - - - // Read the output as lines - omit the first (header) line. - String processLine = commandOutputReader.readLine(); - - - if (processLine != null) { - while ((processLine = commandOutputReader.readLine()) != null) { - - // Remove leading and trailing whitespace. - processLine = processLine.trim(); - - // Split the processes in their info parts - should be only . - String[] processInfo = processLine.split(" ", ProcessInfoNameLength); - - processInfos.add(processInfo); - - - } - } - - - // Parse the process infos - find the pid and get the name. - for (String[] pi : processInfos) { - - - // Ignore all items that don't have the right length. - if (pi.length != ProcessInfoNameLength) { - continue; - } - - // Parse the PID and see if it is the same. - if (!JavaHelper.tryParseInt(pi[PidIndex])) { - continue; - } - - - int pidInternal = Integer.parseInt(pi[PidIndex]); - - - if (pidInternal == pid) { - // The remainder should be the process name. - return pi[ProcessNameIndex]; - } - - } - - - } catch (IOException e) { - // Can ignore the error - return empty string. - return EmptyString; - } - return EmptyString; - - } - - - //endregion - - - //region Object overrides - - - @Override - public String toString() { - return getStatus(); - } - - - //endregion - - - //region SUT implementation - - - /** - * Stops the process. - * @throws SystemStopException could not stop the process. - */ - @Override - public void stop() throws SystemStopException { - - if (_process != null) { - - // Kill process with the Process object we created. - _process.destroy(); - _process = null; - - } else if (_pid != 0) { - - // Kill process given its PID only. - try { - Runtime.getRuntime().exec(String.format(Command_KillProcess, _pid)); - _pid = 0; - } catch (IOException e) { - System.out.println("Could not run the kill command for the process with PID: " + _pid); - } - - } - - } - - - /** - * Checks whether the process is still running. - * @return True if the process is running; False otherwise. - */ - @Override - public boolean isRunning() { - - if (_process != null ) { - return _process.isAlive(); - } else if (_pid != 0) { - - // Check if process is running given its PID only. - // Get a list of running processes with the given PID. - List processInfos = runProcessCommand(String.format(Command_FindProcess, _pid)); - - - if (processInfos == null) { - return false; - } - - - // Lets assume that it could happen that multiple lines are returned - parse and find the requested PID. - for(String[] pi : processInfos) { - - LinuxProcess lp = parseProcess(pi); - - if (lp != null && lp.get_pid() == _pid){ - return true; - } - - } - - } - - return false; - - } - - - /** - * The status of the process. - * @return string representation of the process. - */ - @Override - public String getStatus() { - - if (_process != null) { - return "PID: " + _pid + " - CPU: " + getCpuUsage(this) + "% - Memory: " + (getMemUsage(this) / 1024) + " KB" + " - Process: " + _process.toString(); - } else { - return "PID: " + _pid + " - CPU: " + getCpuUsage(this) + "% - Memory: " + (getMemUsage(this) / 1024) + " KB"; - } - - } - - - //endregion - - - //region Tag overrides - - - /** - * Most likely implements the retrieval of the Tags specified in the method tagDomain. - * @param tag The tag to retrieve the value for. - * @param Type of the value to retrieve. - * @return The value of the tag to retrieve. - */ - @SuppressWarnings("unchecked") - protected T fetch(Tag tag){ - if(tag.equals(Tags.StandardKeyboard)) - return (T)_kbd; - else if(tag.equals(Tags.StandardMouse)) - return (T)_mouse; - else if(tag.equals(Tags.PID)) - return (T)(Long)_pid; - else if(tag.equals(Tags.ProcessHandles)) - return (T)runningProcesses().iterator(); - else if(tag.equals(Tags.SystemActivator)) - return (T) new LinuxProcessActivator(_pid); - return null; - } - - - /** - * Most likely adds new tags to instances of this class. - * @return A new set of tags to be added to instances of this class. - */ - @SuppressWarnings("Duplicates") - protected Set> tagDomain(){ - Set> ret = Util.newHashSet(); - ret.add(Tags.StandardKeyboard); - ret.add(Tags.StandardMouse); - ret.add(Tags.ProcessHandles); - ret.add(Tags.PID); - ret.add(Tags.SystemActivator); - return ret; - } - - - //endregion - - /** - * @author: urueda - */ - @Override public void setNativeAutomationCache() {} - -} diff --git a/linux/src/org/testar/monkey/alayer/linux/LinuxProcessActivator.java b/linux/src/org/testar/monkey/alayer/linux/LinuxProcessActivator.java deleted file mode 100644 index 12878748c..000000000 --- a/linux/src/org/testar/monkey/alayer/linux/LinuxProcessActivator.java +++ /dev/null @@ -1,87 +0,0 @@ -/*************************************************************************************************** -* -* Copyright (c) 2017 Open Universiteit - www.ou.nl -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, -* this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the copyright holder nor the names of its -* contributors may be used to endorse or promote products derived from -* this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -* POSSIBILITY OF SUCH DAMAGE. -*******************************************************************************************************/ - - -package org.testar.monkey.alayer.linux; - - -import org.testar.monkey.Proc; -import org.testar.monkey.alayer.exceptions.ActionFailedException; - - -/** - * Class to activate a Linux process. - */ -public class LinuxProcessActivator implements Proc { - - - //region Global variables - - - private final long _pid; - - - //endregion - - - //region Constructors - - - /** - * Creates a new activator action for a Linux process. - * @param pid The PID of the Linux process to activate. - */ - LinuxProcessActivator(long pid) { - _pid = pid; - } - - - //endregion - - - //region Proc Implementation - - - /** - * Runs the action - activates the Linux process by PID. - */ - @Override - public void run() { - - if (!LinuxProcess.activate(_pid)) { - throw new ActionFailedException("Could not activate the application with PID: " + _pid); - } - - } - - - //endregion - - -} diff --git a/linux/src/org/testar/monkey/alayer/linux/LinuxProcessHandle.java b/linux/src/org/testar/monkey/alayer/linux/LinuxProcessHandle.java deleted file mode 100644 index ad0aa4268..000000000 --- a/linux/src/org/testar/monkey/alayer/linux/LinuxProcessHandle.java +++ /dev/null @@ -1,115 +0,0 @@ -/*************************************************************************************************** -* -* Copyright (c) 2017 Open Universiteit - www.ou.nl -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, -* this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the copyright holder nor the names of its -* contributors may be used to endorse or promote products derived from -* this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -* POSSIBILITY OF SUCH DAMAGE. -*******************************************************************************************************/ - - -package org.testar.monkey.alayer.linux; - -import org.testar.monkey.alayer.devices.ProcessHandle; -import org.testar.monkey.alayer.exceptions.SystemStopException; - -/** - * Another representation of a Linux process. - */ -public class LinuxProcessHandle implements ProcessHandle { - - - //region Global variables - - - private LinuxProcess _process; - - - //endregion - - - //region Constructors - - - /** - * Creates a new Linux process representation from another Linux process representation. - * @param lp A Linux process representation. - */ - LinuxProcessHandle(LinuxProcess lp) { - _process = lp; - } - - /** - * Creates a new Linux process representation from another Linux process representation. - * @param pid The PID of the linux process to create a LinuxProcessHandle representation for. - */ - public LinuxProcessHandle(long pid) { - _process = LinuxProcess.fromPid(pid); - } - - //endregion - - - //region ProcessHandle implementation - - - /** - * Stops the process. - * @throws SystemStopException If an error occurs when trying to stop the process. - */ - @Override - public void kill() throws SystemStopException { - _process.stop(); - } - - - /** - * Determines whether or not the process is currently running. - * @return True if the process is running; False otherwise. - */ - @Override - public boolean isRunning() { - return _process.isRunning(); - } - - - @Override - public String name() { - return _process.getProcessName(); - } - - - /** - * The unique identifier of the Linux process. - * @return The unique identifier of the Linux process. - */ - @Override - public long pid() { - return _process.get_pid(); - } - - - //endregion - - -} diff --git a/linux/src/org/testar/monkey/alayer/linux/SpyMode/DrawableEllipse.java b/linux/src/org/testar/monkey/alayer/linux/SpyMode/DrawableEllipse.java deleted file mode 100644 index 3f86abfbd..000000000 --- a/linux/src/org/testar/monkey/alayer/linux/SpyMode/DrawableEllipse.java +++ /dev/null @@ -1,119 +0,0 @@ -/*************************************************************************************************** -* -* Copyright (c) 2017 Open Universiteit - www.ou.nl -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, -* this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the copyright holder nor the names of its -* contributors may be used to endorse or promote products derived from -* this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -* POSSIBILITY OF SUCH DAMAGE. -*******************************************************************************************************/ - -package org.testar.monkey.alayer.linux.SpyMode; - -import org.testar.monkey.alayer.FillPattern; -import org.testar.monkey.alayer.Pen; - -import java.awt.*; -import java.awt.geom.Ellipse2D; - -/** - * Represents a rectangle that needs to be drawn on screen in Spy- mode. - */ -public class DrawableEllipse extends DrawableObject { - - - //region DrawableObject implementation - - - @Override - public void draw(Graphics2D g2d) { - - g2d.setColor(new Color(_pen.color().red(), _pen.color().green(), _pen.color().blue(), _pen.color().alpha())); - - FillPattern fp = _pen.fillPattern(); - - if (fp == null) { - fp = _defaultPen.fillPattern(); - } - - if (fp == FillPattern.Solid) { - g2d.fill(new Ellipse2D.Double(_location.x, _location.y, _boundingBox.width, _boundingBox.height)); - } else { - g2d.draw(new Ellipse2D.Double(_location.x, _location.y, _boundingBox.width, _boundingBox.height)); - } - - } - - - //endregion - - - //region Properties - - - private Rectangle _boundingBox; - /** - * The bounding box of the ellipse that will be drawn. - * @return The bounding box of the ellipse that will be drawn. - */ - public Rectangle getBoundingBox() { - return _boundingBox; - } - - - //endregion - - - //region Constructors - - - /** - * Creates a new DrawableRect object. - * @param loc The location where this object is located on screen. - * @param p The pen with which this object will be drawn. - * @param dp The default pen with which this object will be drawn as backup. - * @param boundingBox The bounding box of the ellipse that will be drawn. - */ - DrawableEllipse(Point loc, Pen p, Pen dp, Rectangle boundingBox) { - super(loc, p, dp); - - _boundingBox = boundingBox; - - } - - - //endregion - - - //region Object overrides - - - @Override - public String toString() { - return "(" + _location.x + ", " + _location.y + ") - '" + _boundingBox.width + " x " + _boundingBox.height + "'"; - } - - - //endregion - - -} diff --git a/linux/src/org/testar/monkey/alayer/linux/SpyMode/DrawableImage.java b/linux/src/org/testar/monkey/alayer/linux/SpyMode/DrawableImage.java deleted file mode 100644 index ff2a219e0..000000000 --- a/linux/src/org/testar/monkey/alayer/linux/SpyMode/DrawableImage.java +++ /dev/null @@ -1,107 +0,0 @@ -/*************************************************************************************************** -* -* Copyright (c) 2017 Open Universiteit - www.ou.nl -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, -* this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the copyright holder nor the names of its -* contributors may be used to endorse or promote products derived from -* this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -* POSSIBILITY OF SUCH DAMAGE. -*******************************************************************************************************/ - - -package org.testar.monkey.alayer.linux.SpyMode; - -import org.testar.monkey.alayer.Pen; - -import java.awt.*; - -/** - * Represents an image that needs to be drawn on screen in Spy- mode. - */ -public class DrawableImage extends DrawableObject { - - - //region DrawableObject implementation - - - @Override - public void draw(Graphics2D g2d) { - - g2d.setColor(new Color(_pen.color().red(), _pen.color().green(), _pen.color().blue(), _pen.color().alpha())); - throw new UnsupportedOperationException(); - - } - - - //endregion - - - //region Properties - - - private byte[] _bytes; - /** - * The bytes of the image that will be drawn. - * @return The bytes of the image that will be drawn. - */ - public byte[] getBytes() { - return _bytes; - } - - - //endregion - - - //region Constructors - - - /** - * Creates a new DrawableRect object. - * @param loc The location where this object is located on screen. - * @param p The pen with which this object will be drawn. - * @param dp The default pen with which this object will be drawn as backup. - * @param bytes Byte array of an image. - */ - DrawableImage(Point loc, Pen p, Pen dp, byte[] bytes) { - super(loc, p, dp); - - _bytes = bytes; - - } - - - //endregion - - - //region Object overrides - - - @Override - public String toString() { - return "(" + _location.x + ", " + _location.y + ")"; - } - - - //endregion - - -} diff --git a/linux/src/org/testar/monkey/alayer/linux/SpyMode/DrawableLine.java b/linux/src/org/testar/monkey/alayer/linux/SpyMode/DrawableLine.java deleted file mode 100644 index 467a5c74c..000000000 --- a/linux/src/org/testar/monkey/alayer/linux/SpyMode/DrawableLine.java +++ /dev/null @@ -1,107 +0,0 @@ -/*************************************************************************************************** -* -* Copyright (c) 2017 Open Universiteit - www.ou.nl -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, -* this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the copyright holder nor the names of its -* contributors may be used to endorse or promote products derived from -* this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -* POSSIBILITY OF SUCH DAMAGE. -*******************************************************************************************************/ - - -package org.testar.monkey.alayer.linux.SpyMode; - -import org.testar.monkey.alayer.Pen; - -import java.awt.*; - -/** - * Represents a line that needs to be drawn on screen in Spy- mode. - */ -public class DrawableLine extends DrawableObject { - - - //region DrawableObject implementation - - - @Override - public void draw(Graphics2D g2d) { - - g2d.setColor(new Color(_pen.color().red(), _pen.color().green(), _pen.color().blue(), _pen.color().alpha())); - g2d.drawLine(_location.x, _location.y, _target.x, _target.y); - - } - - - //endregion - - - //region Properties - - - private Point _target; - /** - * The target point of the line that will be drawn. - * @return The target point of the line that will be drawn. - */ - public Point getTarget() { - return _target; - } - - - //endregion - - - //region Constructors - - - /** - * Creates a new DrawableRect object. - * @param loc The location where this object is located on screen. - * @param p The pen with which this object will be drawn. - * @param dp The default pen with which this object will be drawn as backup. - * @param target End point of the line to be drawn. - */ - DrawableLine(Point loc, Pen p, Pen dp, Point target) { - super(loc, p, dp); - - _target = target; - - } - - - //endregion - - - //region Object overrides - - - @Override - public String toString() { - return "(" + _location.x + ", " + _location.y + ") to (" + _location.x + ", " + _location.y + ")"; - } - - - //endregion - - -} diff --git a/linux/src/org/testar/monkey/alayer/linux/SpyMode/DrawableObject.java b/linux/src/org/testar/monkey/alayer/linux/SpyMode/DrawableObject.java deleted file mode 100644 index 6a5cfef0a..000000000 --- a/linux/src/org/testar/monkey/alayer/linux/SpyMode/DrawableObject.java +++ /dev/null @@ -1,112 +0,0 @@ -/*************************************************************************************************** -* -* Copyright (c) 2017 Open Universiteit - www.ou.nl -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, -* this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the copyright holder nor the names of its -* contributors may be used to endorse or promote products derived from -* this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -* POSSIBILITY OF SUCH DAMAGE. -*******************************************************************************************************/ - - -package org.testar.monkey.alayer.linux.SpyMode; - - -import org.testar.monkey.alayer.Pen; - -import java.awt.*; - -/** - * - */ -public abstract class DrawableObject { - - - //region Properties - - - protected Point _location; - /** - * The location where this object will be drawn. - * @return The location where this object will be drawn. - */ - public Point getLocation() { - return _location; - } - - - protected Pen _defaultPen; - /** - * The DefaultPen with which this object will be drawn as backup. - * @return The DefaultPen with which this object will be drawn as backup. - */ - public Pen getDefaultPen() { - return _defaultPen; - } - - - protected Pen _pen; - /** - * The Pen with which this object will be drawn. - * @return The Pen with which this object will be drawn. - */ - public Pen getPen() { - return _pen; - } - - - //endregion - - - //region Abstract methods - - - /** - * Draws the object on the graphic context supplied. - * @param g2d The graphics context on/ with which to paint. - */ - public abstract void draw(Graphics2D g2d); - - - //endregion - - - //region Constructors - - - /** - * Creates a new DrawableObject. - * @param loc The location where this object is located on screen. - * @param p The pen with which this object will be drawn. - * @param dp The default pen with which this object will be drawn as backup. - */ - DrawableObject(Point loc, Pen p, Pen dp) { - _location = loc; - _pen = p; - _defaultPen = dp; - } - - - //endregion - - -} diff --git a/linux/src/org/testar/monkey/alayer/linux/SpyMode/DrawableRect.java b/linux/src/org/testar/monkey/alayer/linux/SpyMode/DrawableRect.java deleted file mode 100644 index cf8b3329f..000000000 --- a/linux/src/org/testar/monkey/alayer/linux/SpyMode/DrawableRect.java +++ /dev/null @@ -1,138 +0,0 @@ -/*************************************************************************************************** -* -* Copyright (c) 2017 Open Universiteit - www.ou.nl -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, -* this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the copyright holder nor the names of its -* contributors may be used to endorse or promote products derived from -* this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -* POSSIBILITY OF SUCH DAMAGE. -*******************************************************************************************************/ - - -package org.testar.monkey.alayer.linux.SpyMode; - -import org.testar.monkey.alayer.FillPattern; -import org.testar.monkey.alayer.Pen; - -import java.awt.*; - -/** - * Represents a rectangle that needs to be drawn on screen in Spy- mode. - */ -public class DrawableRect extends DrawableObject { - - - //region DrawableObject implementation - - - @Override - public void draw(Graphics2D g2d) { - - - // TODO: this is a hack that could be looked into to. - // If the color (255,255,0,x) comes through make it completely transparent: - // this is Testar's highlight color in spy-mode. However, it will make the Java window not click-through anymore - // Could catch the mouse-event and simulate it again but this works easier - Testar already has a border around - // every highlighted element anyways. - if (_pen.color().red() == 255 && _pen.color().green() == 255 && _pen.color().blue() == 0) { - g2d.setColor(new Color(0, 0, 0, 0)); - } else { - g2d.setColor(new Color(_pen.color().red(), _pen.color().green(), _pen.color().blue(), _pen.color().alpha())); - } - - Double sw = _pen.strokeWidth(); - - if (sw == null) - sw = _defaultPen.strokeWidth(); - - if (sw != null) - g2d.setStroke(new BasicStroke(sw.floatValue())); - - - FillPattern fp = _pen.fillPattern(); - - if (fp == null) { - fp = _defaultPen.fillPattern(); - } - - if (fp == FillPattern.Solid) { - g2d.fillRect(_rect.x, _rect.y, _rect.width, _rect.height); - } else { - g2d.drawRect(_rect.x, _rect.y, _rect.width, _rect.height); - } - - } - - - //endregion - - - //region Properties - - - private Rectangle _rect; - /** - * The rectangle that will be drawn. - * @return The rectangle that will be drawn. - */ - public Rectangle getRectangle() { - return _rect; - } - - - //endregion - - - //region Constructors - - - /** - * Creates a new DrawableRect object. - * @param loc The location where this object is located on screen. - * @param p The pen with which this object will be drawn. - * @param dp The default pen with which this object will be drawn as backup. - * @param rect The rectangle that will be drawn. - */ - DrawableRect(Point loc, Pen p, Pen dp, Rectangle rect) { - super(loc, p, dp); - - _rect = rect; - - } - - - //endregion - - - //region Object overrides - - - @Override - public String toString() { - return "(" + _location.x + ", " + _location.y + ") - '" + _rect.width + " x " + _rect.height + "'"; - } - - - //endregion - - -} diff --git a/linux/src/org/testar/monkey/alayer/linux/SpyMode/DrawableText.java b/linux/src/org/testar/monkey/alayer/linux/SpyMode/DrawableText.java deleted file mode 100644 index 41b1dc289..000000000 --- a/linux/src/org/testar/monkey/alayer/linux/SpyMode/DrawableText.java +++ /dev/null @@ -1,156 +0,0 @@ -/*************************************************************************************************** -* -* Copyright (c) 2017 Open Universiteit - www.ou.nl -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, -* this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the copyright holder nor the names of its -* contributors may be used to endorse or promote products derived from -* this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -* POSSIBILITY OF SUCH DAMAGE. -*******************************************************************************************************/ - -package org.testar.monkey.alayer.linux.SpyMode; - -import org.testar.monkey.alayer.Pen; -import org.testar.monkey.alayer.linux.util.JavaHelper; - -import java.awt.*; - - -/** - * Represents text that needs to be drawn on screen in Spy- mode. - */ -public class DrawableText extends DrawableObject { - - - //region DrawableObject implementation - - - @Override - public void draw(Graphics2D g2d) { - - - g2d.setColor(new Color(_pen.color().red(), _pen.color().green(), _pen.color().blue(), _pen.color().alpha())); - - - // Set the stroke width. - Double sw = _pen.strokeWidth(); - - if (sw == null) - sw = _defaultPen.strokeWidth(); - - if (sw != null) - g2d.setStroke(new BasicStroke(sw.floatValue())); - - // Create a font. - String fontName = _pen.font(); - Double fontSize = _pen.fontSize(); - Font f; - - - if (JavaHelper.isNullOrWhitespace(fontName)) { - fontName = _defaultPen.font(); - } - if (fontSize == null) { - fontSize = _defaultPen.fontSize(); - } - - // Testar uses 3.0 stroke-width to signal plain and 5.0 to signal Bold. - if (sw != null && sw == 5.0) { - f = new Font(fontName, Font.BOLD, fontSize.intValue()); - } else { - f = new Font(fontName, Font.PLAIN, fontSize.intValue()); - } - - - g2d.setFont(f); - - - - // Displace the location. - FontMetrics fMetrics = g2d.getFontMetrics(f); - - - // TODO: Lets do a bit of cheating - Bold text is inside tooltip: shift it down and a bit to the right - plain text is edit box: centre it. - // The 25 is the height of the textbox in this case - the method should actually get the height of the widget we're dealing with... - if (sw != null && sw == 5.0) { - g2d.drawString(_text, _location.x + 5, _location.y + 15); - } else { - g2d.drawString(_text, _location.x - (fMetrics.stringWidth(_text) / 2), _location.y - (fMetrics.getHeight() / 2) + (25 / 2)); - } - - - } - - - //endregion - - - //region Properties - - - private String _text; - /** - * The text that will be drawn. - * @return The text that will be drawn. - */ - public String getText() { - return _text; - } - - - //endregion - - - //region Constructors - - - /** - * Creates a new DrawableText object. - * @param loc The location where this object is located on screen. - * @param p The pen with which this object will be drawn. - * @param dp The default pen with which this object will be drawn as backup. - * @param txt The text that will be drawn. - */ - DrawableText(Point loc, Pen p, Pen dp, String txt) { - super(loc, p, dp); - - _text = txt; - - } - - - //endregion - - - //region Object overrides - - - @Override - public String toString() { - return "(" + _location.x + ", " + _location.y + ") - '" + _text + "'"; - } - - - //endregion - - -} diff --git a/linux/src/org/testar/monkey/alayer/linux/SpyMode/DrawingPane.java b/linux/src/org/testar/monkey/alayer/linux/SpyMode/DrawingPane.java deleted file mode 100644 index bac3e7309..000000000 --- a/linux/src/org/testar/monkey/alayer/linux/SpyMode/DrawingPane.java +++ /dev/null @@ -1,94 +0,0 @@ -/*************************************************************************************************** -* -* Copyright (c) 2017 Open Universiteit - www.ou.nl -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, -* this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the copyright holder nor the names of its -* contributors may be used to endorse or promote products derived from -* this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -* POSSIBILITY OF SUCH DAMAGE. -*******************************************************************************************************/ - -package org.testar.monkey.alayer.linux.SpyMode; - -import javax.swing.*; -import java.awt.*; -import java.util.concurrent.CopyOnWriteArrayList; - -public class DrawingPane extends JPanel { - - private static final long serialVersionUID = 5078094486379747059L; - private CopyOnWriteArrayList _content = new CopyOnWriteArrayList<>(); - - - /** - * Adds an object to draw on the pane. - * @param c The content to draw. - * @return True if successfully added; False otherwise. - */ - boolean addDrawableContent(DrawableObject c) { - - _content.add(c); - this.repaint(); - return true; - - } - - - /** - * Clears the pane from content. - */ - void clearDrawableContent() { - _content.clear(); - } - - - DrawingPane() { - setOpaque(false); - } - - - @Override - public Dimension getPreferredSize() { - return new Dimension(1920, 1080); - } - - - @Override - protected void paintComponent(Graphics g) { - super.paintComponent(g); - - Graphics2D g2d = (Graphics2D) g.create(); - - - g2d.setColor(Color.RED); - g2d.drawRect(0, 0, getWidth() - 1, getHeight() - 1); - - - for (DrawableObject c: _content) { - c.draw(g2d); - } - - g2d.dispose(); - - } - -} diff --git a/linux/src/org/testar/monkey/alayer/linux/SpyMode/JavaScreenCanvas.java b/linux/src/org/testar/monkey/alayer/linux/SpyMode/JavaScreenCanvas.java deleted file mode 100644 index 9043e9c91..000000000 --- a/linux/src/org/testar/monkey/alayer/linux/SpyMode/JavaScreenCanvas.java +++ /dev/null @@ -1,357 +0,0 @@ -/*************************************************************************************************** -* -* Copyright (c) 2017 - 2025 Universitat Politecnica de Valencia - www.upv.es -* Copyright (c) 2018 - 2025 Open Universiteit - www.ou.nl -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, -* this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the copyright holder nor the names of its -* contributors may be used to endorse or promote products derived from -* this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -* POSSIBILITY OF SUCH DAMAGE. -*******************************************************************************************************/ - -package org.testar.monkey.alayer.linux.SpyMode; - -import org.testar.monkey.Assert; -import org.testar.monkey.Pair; -import org.testar.monkey.alayer.Canvas; -import org.testar.monkey.alayer.Pen; - -import javax.swing.*; -import java.awt.*; - -public class JavaScreenCanvas implements Canvas { - - - //region Global variables - - - private boolean _running; - private DrawingPane _paneReference; - private JFrame _frameReference; - - //endregion - - - //region Canvas implementation - - - //region Properties - - - private double _width; - @Override - public double width() { - return _width; - } - - - private double _height; - @Override - public double height() { - return _height; - } - - - private double _x; - @Override - public double x() { - return _x; - } - - - private double _y; - @Override - public double y() { - return _y; - } - - - private Pen _defaultPen; - @Override - public Pen defaultPen() { - return _defaultPen; - } - - - //endregion - - - @Override - public void begin() { - runningCheck(); - } - - - @Override - public void end() { - // Not much to do here. - } - - - @Override - public void release() { - - if(!_running) - return; - _running = false; - - _frameReference.setVisible(false); - - } - - @Override - public void paintBatch() { - // Not implemented here - } - - /** - * Creates a pair of values for a text, most likely: a letter width of 2 and a height of 20. - * @param pen A pen which is not needed. - * @param text The text to get metrics on. - * @return A pair of values. - */ - @Override - public Pair textMetrics(Pen pen, String text) { - Assert.notNull(pen, text); - return Pair.from(text.length() * 2., 20.); - } - - - /** - * Clears the drawing area. - * @param x X location of the rectangle used to clear the drawing area - deprecated. - * @param y Y location of the rectangle used to clear the drawing area - deprecated. - * @param width Width of the rectangle used to clear the drawing area - deprecated. - * @param height Height of the rectangle used to clear the drawing area - deprecated. - */ - @Override - public void clear(double x, double y, double width, double height) { - - runningCheck(); - //System.out.println("Clear: (" + x + ", " + y + ")."); - _paneReference.clearDrawableContent(); - - } - - - @Override - public void line(Pen pen, double x1, double y1, double x2, double y2) { - - runningCheck(); - //System.out.println("Draw Line: (" + x1 + ", " + y1 + ")."); - _paneReference.addDrawableContent(new DrawableLine(new Point(Double.valueOf(x1).intValue(), Double.valueOf(y1).intValue()), pen, _defaultPen, - new Point(Double.valueOf(x2).intValue(), Double.valueOf(y2).intValue()))); - - } - - - @Override - public void text(Pen pen, double x, double y, double angle, String text) { - - runningCheck(); - //System.out.println("Draw Text: (" + x + ", " + y + ")."); - _paneReference.addDrawableContent(new DrawableText(new Point(Double.valueOf(x).intValue(), Double.valueOf(y).intValue()), pen, _defaultPen, text)); - - } - - - @Override - public void ellipse(Pen pen, double x, double y, double width, double height) { - - runningCheck(); - //System.out.println("Draw Ellipse: (" + x + ", " + y + ")."); - _paneReference.addDrawableContent(new DrawableEllipse(new Point(Double.valueOf(x).intValue(), Double.valueOf(y).intValue()), pen, _defaultPen, - new Rectangle(Double.valueOf(x).intValue(), Double.valueOf(y).intValue(), Double.valueOf(width).intValue(), Double.valueOf(height).intValue()))); - - } - - - @Override - public void triangle(Pen pen, double x1, double y1, double x2, double y2, double x3, double y3) { - //System.out.println("Draw Triangle: (" + x1 + ", " + y1 + ")."); - throw new UnsupportedOperationException(); - } - - @Override - public void image(Pen pen, double x, double y, double width, double height, int[] image, int imageWidth, int imageHeight) { - - runningCheck(); - //System.out.println("Draw Image: (" + x + ", " + y + ")."); - //_paneReference.addDrawableContent(new DrawableImage(new Point(new Double(x).intValue(), new Double(y).intValue()), pen, _defaultPen, image)); - throw new UnsupportedOperationException(); - } - - - @Override - public void rect(Pen pen, double x, double y, double width, double height) { - - runningCheck(); - //System.out.println("Draw Rect: (" + x + ", " + y + ")."); - _paneReference.addDrawableContent(new DrawableRect(new Point(Double.valueOf(x).intValue(), Double.valueOf(y).intValue()), pen, _defaultPen, - new Rectangle(Double.valueOf(x).intValue(), Double.valueOf(y).intValue(), Double.valueOf(width).intValue(), Double.valueOf(height).intValue()))); - - } - - - //endregion - - - //region Constructors - - - private JavaScreenCanvas(int x, int y, int width, int height, Pen defaultPen) { - - - Assert.notNull(defaultPen); - Assert.isTrue(width >= 0 && height >= 0); - - _x = x; - _y = y; - _width = width; - _height = height; - _defaultPen = defaultPen; - - EventQueue.invokeLater(() -> { - - - try { - UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); - } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { - ex.printStackTrace(); - } - - - // Set a title for reference. - _frameReference = new JFrame("Testar - Spy window"); - - - // No title bar, no task bar, always on top. - _frameReference.setUndecorated(true); - _frameReference.setType(Window.Type.UTILITY); - _frameReference.setAlwaysOnTop(true); - _frameReference.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); - - - // Make the window invisible. - _frameReference.setBackground(new Color(0, 0, 0, 0)); - - - // Set the size and location. - _frameReference.setLocation(x, y); - _frameReference.setSize(width, height); - - - // Add content. - _paneReference = new DrawingPane(); - _frameReference.add(_paneReference); - - - // frame.pack(); - - _frameReference.setLocationRelativeTo(null); - _frameReference.setVisible(true); - - - // Signal the window is currently active. - _running = true; - - - }); - - } - - - //endregion - - - //region Other necessary methods - - - /** - * Creates a window covering the primary monitor. - * @param defaultPen The default pen used to draw stuff. - * @return An instance of a window to draw on in Spy- mode. - */ - public static JavaScreenCanvas fromPrimaryMonitor(Pen defaultPen){ - - // Get the primary monitor bounds and create a window covering the entire screen. - Rectangle monitorBounds = getPrimaryMonitorBounds(); - - return new JavaScreenCanvas(monitorBounds.x, monitorBounds.y, monitorBounds.width, monitorBounds.height, defaultPen); - - } - - - /** - * Checks whether the Spy- window is showing. If not, it will throw an IllegalStateException. - */ - private void runningCheck() { - if(!_running) - throw new IllegalStateException("Linux Spy window is not running!"); - } - - - /** - * Called by GC to clean up this object. - */ - public void finalize() { - release(); - } - - - //endregion - - - //region Helper methods - - - /** - * Gets the bounds of the primary monitor. - * @return A rectangle containing the location and bounds of the primary monitor. - */ - private static Rectangle getPrimaryMonitorBounds() { - - // Get primary monitor resolution. - GraphicsEnvironment g = GraphicsEnvironment.getLocalGraphicsEnvironment(); - GraphicsDevice[] devices = g.getScreenDevices(); - - for (GraphicsDevice device : devices) { - - Rectangle monitorBounds = device.getDefaultConfiguration().getBounds(); - - if (monitorBounds.x == 0 && monitorBounds.y == 0) { - // Primary monitor starts at (0, 0). - return monitorBounds; - } - - } - - System.out.println("Could not find primary monitor! Assume 1920 x 1080 @ (0, 0)"); - return new Rectangle(0,0, 1920, 1080); - - } - - - //endregion - - -} diff --git a/linux/src/org/testar/monkey/alayer/linux/atspi/AtSpiAccessible.java b/linux/src/org/testar/monkey/alayer/linux/atspi/AtSpiAccessible.java deleted file mode 100644 index 7af2b5548..000000000 --- a/linux/src/org/testar/monkey/alayer/linux/atspi/AtSpiAccessible.java +++ /dev/null @@ -1,486 +0,0 @@ -/*************************************************************************************************** -* -* Copyright (c) 2017 Open Universiteit - www.ou.nl -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, -* this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the copyright holder nor the names of its -* contributors may be used to endorse or promote products derived from -* this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -* POSSIBILITY OF SUCH DAMAGE. -*******************************************************************************************************/ - - -package org.testar.monkey.alayer.linux.atspi; - - -import org.testar.monkey.alayer.linux.util.BridJHelper; -import org.testar.monkey.alayer.linux.atspi.enums.AtSpiRoles; -import org.testar.monkey.alayer.linux.glib.GArray; -import org.testar.monkey.alayer.linux.glib.GHashTable; - -import java.util.ArrayList; -import java.util.List; - - -/** - * Java implementation of the AtSpiAccessible object. - */ -public class AtSpiAccessible { - - - //region Properties - - - private long _accessiblePtr; - public long accessiblePtr() { - return _accessiblePtr; - } - - - private String _name; - public String name() { - return BridJHelper.convertToString(LibAtSpi.atspi_accessible_get_name(_accessiblePtr, 0)); - } - - - private String _description; - public String description() { - return BridJHelper.convertToString(LibAtSpi.atspi_accessible_get_description(_accessiblePtr, 0)); - } - - - private long _parentPtr; - public long parentPtr() { - return LibAtSpi.atspi_accessible_get_parent(_accessiblePtr, 0); - } - - - private AtSpiAccessible _parent; - public AtSpiAccessible parent() { - return _parent; - } - - - private int _childCount; - public int childCount() { - return LibAtSpi.atspi_accessible_get_child_count(_accessiblePtr, 0); - } - - - private List _children; - public List children() { return getAccessibleChildren(this); } - - - private int _indexInParent; - public int indexInParent() { - return LibAtSpi.atspi_accessible_get_index_in_parent(_accessiblePtr, 0); - } - - - // TODO: relation_set. - - - private AtSpiRoles _role; - public AtSpiRoles role() { - return AtSpiRoles.values()[LibAtSpi.atspi_accessible_get_role(_accessiblePtr, 0)]; - } - - - private String _roleName; - public String roleName() { - return BridJHelper.convertToString(LibAtSpi.atspi_accessible_get_role_name(_accessiblePtr, 0)); - } - - - private AtSpiStateSet _states; - public AtSpiStateSet states() { - return AtSpiStateSet.CreateInstance(LibAtSpi.atspi_accessible_get_state_set(_accessiblePtr)); - } - - - private List _relations; - public List relations() { - return createRelationList(LibAtSpi.atspi_accessible_get_relation_set(_accessiblePtr, 0)); - } - - - private GHashTable _attributes; - public GHashTable attributes() { - return GHashTable.CreateInstance(LibAtSpi.atspi_accessible_get_attributes(_accessiblePtr, 0)); - } - - - private GArray _attributesAsArray; - public GArray attributesAsArray() { return GArray.CreateInstance(LibAtSpi.atspi_accessible_get_attributes_as_array(_accessiblePtr, 0), String.class); } - - - private String _toolkitName; - public String toolkitName() { - return BridJHelper.convertToString(LibAtSpi.atspi_accessible_get_toolkit_name(_accessiblePtr, 0)); - } - - - private String _toolkitVersion; - public String toolkitVersion() { - return BridJHelper.convertToString(LibAtSpi.atspi_accessible_get_toolkit_version(_accessiblePtr, 0)); - } - - - // TODO: application. - - - private AtSpiAction _action; - public AtSpiAction action() { return AtSpiAction.CreateInstance(LibAtSpi.atspi_accessible_get_action_iface(_accessiblePtr)); } - - - private AtSpiComponent _component; - public AtSpiComponent component() { return AtSpiComponent.CreateInstance(LibAtSpi.atspi_accessible_get_component_iface(_accessiblePtr)); } - - - private AtSpiValue _value; - public AtSpiValue value() { return AtSpiValue.CreateInstance(LibAtSpi.atspi_accessible_get_value_iface(_accessiblePtr)); } - - - private GArray _interfaces; - public GArray interfaces() { - return GArray.CreateInstance(LibAtSpi.atspi_accessible_get_interfaces(_accessiblePtr), String.class); - } - - - //endregion - - - //region Constructors - - - /** - * Default empty constructor. - */ - private AtSpiAccessible() { - - } - - - /** - * Creates a new instance of an AtSpiAccessible object from a pointer. - * @param accessiblePtr Pointer to the AtSpiAccessible object. - * @return A Java instance of an AtSpiAccessible object. - */ - public static AtSpiAccessible CreateInstance(long accessiblePtr) { - return CreateInstance(accessiblePtr, null); - } - - - /** - * Creates a new instance of an AtSpiAccessible object from a pointer. - * @param accessiblePtr Pointer to the AtSpiAccessible object. - * @param parent The parent of the AtSpiAccessible object to create. - * @return A Java instance of an AtSpiAccessible object. - */ - public static AtSpiAccessible CreateInstance(long accessiblePtr, AtSpiAccessible parent) { - - - if (accessiblePtr == 0) { - return null; - } - - - // Create a new instance. - AtSpiAccessible aObj = new AtSpiAccessible(); - - - // Fill the instance's properties. - //fillInstance(windowPtr, aObj, parent); - - - aObj._accessiblePtr = accessiblePtr; - - - if (parent == null && aObj.parentPtr() != 0) { - aObj._parent = AtSpiAccessible.CreateInstance(aObj._parentPtr); - } else if (parent != null) { - aObj._parent = parent; - } - - - return aObj; - - } - - - /** - * Fills an AtSpiAccessible object's information. - * @param accessiblePtr Pointer to the AtSpiAccessible object. - * @param aObj The Java instance of an AtSpiAccessible object. - * @param parent The parent of the AtSpiAccessible object to fill the information for. - */ - private static void fillInstance(long accessiblePtr, AtSpiAccessible aObj, AtSpiAccessible parent) { - - - // Fill the properties with the information. - aObj._accessiblePtr = accessiblePtr; - aObj._name = BridJHelper.convertToString(LibAtSpi.atspi_accessible_get_name(accessiblePtr, 0)); - aObj._description = BridJHelper.convertToString(LibAtSpi.atspi_accessible_get_description(accessiblePtr, 0)); - aObj._parentPtr = LibAtSpi.atspi_accessible_get_parent(accessiblePtr, 0); - - if (parent == null && aObj._parentPtr != 0) { - aObj._parent = AtSpiAccessible.CreateInstance(aObj._parentPtr); - } else if (parent != null) { - aObj._parent = parent; - } - - aObj._childCount = LibAtSpi.atspi_accessible_get_child_count(accessiblePtr, 0); - aObj._children = getAccessibleChildren(aObj); - aObj._indexInParent = LibAtSpi.atspi_accessible_get_index_in_parent(accessiblePtr, 0); - aObj._role = AtSpiRoles.values()[LibAtSpi.atspi_accessible_get_role(accessiblePtr, 0)]; - aObj._roleName = BridJHelper.convertToString(LibAtSpi.atspi_accessible_get_role_name(accessiblePtr, 0)); - aObj._states = AtSpiStateSet.CreateInstance(LibAtSpi.atspi_accessible_get_state_set(accessiblePtr)); - - if (aObj._states != null) { - aObj._states.retrieveStates(); - } - - aObj._attributes = GHashTable.CreateInstance(LibAtSpi.atspi_accessible_get_attributes(accessiblePtr, 0)); - aObj._attributesAsArray = GArray.CreateInstance(LibAtSpi.atspi_accessible_get_attributes_as_array(accessiblePtr, 0), String.class); - aObj._toolkitName = BridJHelper.convertToString(LibAtSpi.atspi_accessible_get_toolkit_name(accessiblePtr, 0)); - aObj._toolkitVersion = BridJHelper.convertToString(LibAtSpi.atspi_accessible_get_toolkit_version(accessiblePtr, 0)); - aObj._action = AtSpiAction.CreateInstance(LibAtSpi.atspi_accessible_get_action_iface(accessiblePtr)); - aObj._component = AtSpiComponent.CreateInstance(LibAtSpi.atspi_accessible_get_component_iface(accessiblePtr)); - - if (aObj._component != null) { - aObj._component.retrieveInformation(true); - } - - aObj._interfaces = GArray.CreateInstance(LibAtSpi.atspi_accessible_get_interfaces(accessiblePtr), String.class); - - aObj._value = AtSpiValue.CreateInstance(LibAtSpi.atspi_accessible_get_value_iface(accessiblePtr)); - - if (aObj._value != null) { - aObj._value.retrieveInformation(); - } - - aObj._relations = createRelationList(LibAtSpi.atspi_accessible_get_relation_set(accessiblePtr, 0)); - - if (aObj._relations != null) { - for (AtSpiRelation r : aObj._relations) { - // Don't get the tree since it will be way too heavy and might cause endless loops. - r.retrieveInformation(false); - } - } - - } - - - //endregion - - - //region AtSpiAccessible Functionality - - - /** - * Sets all of the descendants for this accessible object. - * @param fillInfo Whether to create a tree with complete info or just parent - child relations. - */ - public void createTree(boolean fillInfo) { - - - // Create a complete tree with full info. - if (fillInfo) { - retrieveAccessibleInfoTree(); - return; - } - - - // Only create parent - child relations. - _children = getAccessibleChildren(this); - - for (AtSpiAccessible child : _children) { - child.createTree(fillInfo); - } - - } - - - /** - * Fills all the data of the AtSpiAccessible object - mostly for testing purposes: readily available data. - */ - public void retrieveAccessibleInfo() { - fillInstance(_accessiblePtr, this, null); - } - - - /** - * Fills all the data of the AtSpiAccessible object but not the relations - mostly for testing purposes: readily available data. - */ - public void retrieveAccessibleInfoNoRelations() { - fillInstance(_accessiblePtr, this, null); - } - - - /** - * Gets all information for all of the descendants for this accessible object. - */ - public void retrieveAccessibleInfoTree() { - - fillInstance(_accessiblePtr, this, null); - - for (AtSpiAccessible child : _children) { - child.retrieveAccessibleInfoTree(); - } - - } - - - //endregion - - - //region Helper functions - - - /** - * Gets all children pointers of an AtSpiAccessible object. - * @param accessiblePtr A pointer to the AtspiAccessible object on which to operate. - * @return A list of pointers to the children AtspiAccessible objects. - */ - public static List getAccessibleChildrenPtrs(long accessiblePtr) { - - - ArrayList children = new ArrayList<>(); - - - // First get the number of children. - int childCount = LibAtSpi.atspi_accessible_get_child_count(accessiblePtr, 0); - - - // Call the function numerous times to get all children. - for (int i = 0; i < childCount; i++) { - - long childPtr = LibAtSpi.atspi_accessible_get_child_at_index(accessiblePtr, i, 0); - - if (childPtr != 0) { - children.add(childPtr); - } - - } - - - return children; - - - } - - - /** - * Gets all children of an AtSpiAccessible object. - * @param accessiblePtr A pointer to the AtspiAccessible object on which to operate. - * @return A list of children AtspiAccessible objects. - */ - public static List getAccessibleChildren(long accessiblePtr) { - return getAccessibleChildren(AtSpiAccessible.CreateInstance(accessiblePtr)); - } - - - /** - * Gets all children of an AtSpiAccessible object. - * @param parent The parent of the children to get. - * @return A list of children AtspiAccessible objects. - */ - public static List getAccessibleChildren(AtSpiAccessible parent) { - - - ArrayList children = new ArrayList<>(); - - - // Get the pointers to the children. - List childPtrs = getAccessibleChildrenPtrs(parent.accessiblePtr()); - - - // For each pointer create a new instance of AtSpiAccessible. - for (long childPtr : childPtrs) { - - AtSpiAccessible childInstance = AtSpiAccessible.CreateInstance(childPtr, parent); - - if (childInstance != null) { - children.add(childInstance); - } - - } - - - return children; - - - } - - - /** - * Turns a pointer to a GArray containing pointer to AtSpiRelation objects into a list of AtSpiRelations. - * @param relationsArrayPtr Pointer to a GArray containing pointers to AtSpiRelation objects. - * @return A list of AtSpiRelations. - */ - private static List createRelationList(long relationsArrayPtr) { - - - GArray relationPtrs = GArray.CreateInstance(relationsArrayPtr, Long.class); - - - if (relationPtrs == null) { - return null; - } - - ArrayList rs = new ArrayList<>(); - - for (Long ptr : relationPtrs.elements()) { - - AtSpiRelation r = AtSpiRelation.CreateInstance(ptr); - - if (r != null) { - rs.add(r); - } - - } - - - return rs; - - } - - - //endregion - - - //region Object overrides - - - /** - * Returns a string representation of an AtSpiAccessible object. - * @return Returns a string representation of an AtSpiAccessible object. - */ - @Override - public String toString() { - return "Name: " + _name + " - Role: " + _roleName + " - Children: " + _childCount; - } - - - //endregion - - -} diff --git a/linux/src/org/testar/monkey/alayer/linux/atspi/AtSpiAction.java b/linux/src/org/testar/monkey/alayer/linux/atspi/AtSpiAction.java deleted file mode 100644 index 69e38b60f..000000000 --- a/linux/src/org/testar/monkey/alayer/linux/atspi/AtSpiAction.java +++ /dev/null @@ -1,151 +0,0 @@ -/*************************************************************************************************** -* -* Copyright (c) 2017 Open Universiteit - www.ou.nl -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, -* this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the copyright holder nor the names of its -* contributors may be used to endorse or promote products derived from -* this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -* POSSIBILITY OF SUCH DAMAGE. -*******************************************************************************************************/ - - -package org.testar.monkey.alayer.linux.atspi; - - -import org.testar.monkey.alayer.linux.util.BridJHelper; - -import java.util.ArrayList; -import java.util.List; - - -/** - * Java implementation of an AtSpiAction object. - */ -public class AtSpiAction { - - - //region Properties - - - private long _actionPtr; - public long actionPtr() { - return _actionPtr; - } - - - - public int actionCount() { - return LibAtSpi.atspi_action_get_n_actions(_actionPtr, 0); - } - - - private List _actions; - public List actions() { return _actions; } - - - //endregion - - - //region Constructors - - - /** - * Default empty constructor. - */ - private AtSpiAction() { - - } - - - /** - * Creates a new instance of an AtSpiAction object from a pointer. - * @param actionPtr Pointer to the AtSpiAction object. - * @return A Java instance of an AtSpiAction object. - */ - public static AtSpiAction CreateInstance(long actionPtr) { - - - if (actionPtr == 0) { - return null; - } - - - // Create a new instance. - AtSpiAction aObj = new AtSpiAction(); - - - // Fill the instance's properties. - aObj._actionPtr = actionPtr; - - - ArrayList actions = new ArrayList<>(); - - for (int i = 0; i < aObj.actionCount(); i++) { - - AtSpiActionInfo ai = new AtSpiActionInfo(); - - ai.name = BridJHelper.convertToString(LibAtSpi.atspi_action_get_action_name(actionPtr, i, 0)); - ai.index = i; - ai.description = BridJHelper.convertToString(LibAtSpi.atspi_action_get_action_description(actionPtr, i, 0)); - ai.keyBinding = BridJHelper.convertToString(LibAtSpi.atspi_action_get_key_binding(actionPtr, i, 0)); - - actions.add(ai); - } - - aObj._actions = actions; - - return aObj; - - } - - - //endregion - - - /** - * Performs an action on the AtSpiAccessible object this action belongs to. The action run is specified by - * an index attainable from the AtSpiActionInfo. - * @param actionIndex The index of the action to run. - * @return True if action performed successfully; False otherwise. - */ - public boolean invoke(int actionIndex) { - return LibAtSpi.atspi_action_do_action(_actionPtr, actionIndex, 0); - } - - - //region Object overrides - - - /** - * Returns a string representation of an AtSpiAction object. - * @return Returns a string representation of an AtSpiAction object. - */ - @Override - public String toString() { - return "Action count: " + actionCount(); - } - - - //endregion - - -} diff --git a/linux/src/org/testar/monkey/alayer/linux/atspi/AtSpiActionInfo.java b/linux/src/org/testar/monkey/alayer/linux/atspi/AtSpiActionInfo.java deleted file mode 100644 index 307cc8bd4..000000000 --- a/linux/src/org/testar/monkey/alayer/linux/atspi/AtSpiActionInfo.java +++ /dev/null @@ -1,61 +0,0 @@ -/*************************************************************************************************** -* -* Copyright (c) 2017 Open Universiteit - www.ou.nl -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, -* this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the copyright holder nor the names of its -* contributors may be used to endorse or promote products derived from -* this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -* POSSIBILITY OF SUCH DAMAGE. -*******************************************************************************************************/ - - -package org.testar.monkey.alayer.linux.atspi; - -/** - * Information on an AtSpiAction. - */ -public class AtSpiActionInfo { - - - public String name; - public String description; - public String keyBinding; - public int index; - - - //region Object overrides - - - /** - * Returns a string representation of an AtSpiAccessible object. - * @return Returns a string representation of an AtSpiAccessible object. - */ - @Override - public String toString() { - return "Action: " + name + " - Description: " + description; - } - - - //endregion - - -} diff --git a/linux/src/org/testar/monkey/alayer/linux/atspi/AtSpiComponent.java b/linux/src/org/testar/monkey/alayer/linux/atspi/AtSpiComponent.java deleted file mode 100644 index 6bec6f012..000000000 --- a/linux/src/org/testar/monkey/alayer/linux/atspi/AtSpiComponent.java +++ /dev/null @@ -1,267 +0,0 @@ -/*************************************************************************************************** -* -* Copyright (c) 2017 Open Universiteit - www.ou.nl -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, -* this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the copyright holder nor the names of its -* contributors may be used to endorse or promote products derived from -* this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -* POSSIBILITY OF SUCH DAMAGE. -*******************************************************************************************************/ - - -package org.testar.monkey.alayer.linux.atspi; - - -import org.testar.monkey.alayer.linux.atspi.enums.AtSpiComponentLayers; -import org.testar.monkey.alayer.linux.atspi.enums.AtSpiCoordTypes; - - -/** - * Java implementation of an AtSpiComponent object - An interface implemented by objects which have onscreen visual representations. - */ -public class AtSpiComponent { - - - //region Properties - - - private long _componentPtr; - public long componentPtr() { - return _componentPtr; - } - - - private AtSpiRect _extentsOnScreen; - /** - * The bounding box of the component relative to the screen. - * @return The bounding box of the component relative to the screen. - */ - public AtSpiRect extentsOnScreen() { - return AtSpiRect.CreateInstance(LibAtSpi.atspi_component_get_extents(_componentPtr, AtSpiCoordTypes.Screen.ordinal(), 0)); - } - - - private AtSpiRect _extentsOnWindow; - /** - * The bounding box of the component relative to the window. - * @return The bounding box of the component relative to the window. - */ - public AtSpiRect extentsOnWindow() { - return AtSpiRect.CreateInstance(LibAtSpi.atspi_component_get_extents(_componentPtr, AtSpiCoordTypes.Window.ordinal(), 0)); - } - - - private AtSpiPoint _positionOnScreen; - /** - * Gets the position of the AtspiComponent in screen coordinates. - * @return The position of the AtspiComponent in screen coordinates. - */ - public AtSpiPoint positionOnScreen() { - return AtSpiPoint.CreateInstance(LibAtSpi.atspi_component_get_position(_componentPtr, AtSpiCoordTypes.Screen.ordinal(), 0)); - } - - - private AtSpiPoint _positionOnWindow; - /** - * Gets the position of the AtspiComponent in window coordinates. - * @return The position of the AtspiComponent in window coordinates. - */ - public AtSpiPoint positionOnWindow() { - return AtSpiPoint.CreateInstance(LibAtSpi.atspi_component_get_position(_componentPtr, AtSpiCoordTypes.Window.ordinal(), 0)); - } - - - private AtSpiPoint _size; - /** - * Gets the size of the AtspiComponent. - * @return The size of the AtspiComponent. - */ - public AtSpiPoint size() { - return AtSpiPoint.CreateInstance(LibAtSpi.atspi_component_get_size(_componentPtr, 0)); - } - - - private AtSpiComponentLayers _layer; - /** - * Queries which layer the component is painted into, to help determine its visibility in terms of stacking order. - * @return The layer the component is painted into. - */ - public AtSpiComponentLayers layer() { - - int val = LibAtSpi.atspi_component_get_layer(_componentPtr, 0); - - - // Sometimes an invalid value gets returned - link it to the Invalid enum value. - if (val == -1) { - val = 0; - } - - return AtSpiComponentLayers.values()[val]; - - } - - - private short _mdiZOrder; - /** - * Queries the z stacking order of a component which is in the MDI or window layer - * (Bigger z-order numbers mean nearer the top). - * @return Returns a short indicating the stacking order of the component in the MDI layer, - * or -1 if the component is not in the MDI layer. - */ - public short mdiZOrder() { - return LibAtSpi.atspi_component_get_mdi_z_order(_componentPtr, 0); - } - - - //endregion - - - //region Constructors + Initialization - - - /** - * Default empty constructor. - */ - private AtSpiComponent() { - - } - - - /** - * Creates a new instance of an AtSpiComponent object from a pointer. - * @param componentPtr Pointer to the AtSpiComponent object. - * @return A Java instance of an AtSpiComponent object. - */ - public static AtSpiComponent CreateInstance(long componentPtr) { - - - if (componentPtr == 0) { - return null; - } - - - // Create a new instance. - AtSpiComponent cObj = new AtSpiComponent(); - - - // Fill the instance's properties. - cObj._componentPtr = componentPtr; - - - return cObj; - - } - - - /** - * Fills an AtSpiComponent object's information. - * @param componentPtr Pointer to the AtSpiComponent object. - * @param cObj The Java instance of an AtSpiComponent object. - */ - private static void fillInstance(long componentPtr, AtSpiComponent cObj, boolean light) { - - - // Fill the properties with the information. - //cObj._componentPtr = componentPtr; - - - // These operations are quite heavy so better only do them if explicitly asked. - if (!light) { - - cObj._extentsOnScreen = AtSpiRect.CreateInstance(LibAtSpi.atspi_component_get_extents(componentPtr, AtSpiCoordTypes.Screen.ordinal(), 0)); - cObj._extentsOnWindow = AtSpiRect.CreateInstance(LibAtSpi.atspi_component_get_extents(componentPtr, AtSpiCoordTypes.Window.ordinal(), 0)); - - cObj._positionOnScreen = AtSpiPoint.CreateInstance(LibAtSpi.atspi_component_get_position(componentPtr, AtSpiCoordTypes.Screen.ordinal(), 0)); - cObj._positionOnWindow = AtSpiPoint.CreateInstance(LibAtSpi.atspi_component_get_position(componentPtr, AtSpiCoordTypes.Window.ordinal(), 0)); - - cObj._size = AtSpiPoint.CreateInstance(LibAtSpi.atspi_component_get_size(componentPtr, 0)); - - } - - - int val = LibAtSpi.atspi_component_get_layer(componentPtr, 0); - - - // Sometimes an invalid value gets returned - link it to the Invalid enum value. - if (val == -1) { - val = 0; - } - - cObj._layer = AtSpiComponentLayers.values()[val]; - - - cObj._mdiZOrder = LibAtSpi.atspi_component_get_mdi_z_order(componentPtr, 0); - - - } - - - //endregion - - - //region Component functionality - - - /** - * Fills the instance with data for debug purposes. - */ - public void retrieveInformation(boolean light) { - fillInstance(_componentPtr, this, light); - } - - - /** - * Attempts to set the keyboard input focus to the specified AtspiComponent. - * @return TRUE if successful, FALSE otherwise. - */ - public boolean grabFocus() { - return LibAtSpi.atspi_component_grab_focus(_componentPtr, 0); - - - } - - - //endregion - - - //region Object overrides - - - /** - * Returns a string representation of an AtSpiComponent object. - * @return Returns a string representation of an AtSpiComponent object. - */ - @Override - public String toString() { - - if (_layer != null) { - return "Layer: " + _layer.toString(); - } - - return "Layer: " + layer().toString(); - } - - - //endregion - - -} diff --git a/linux/src/org/testar/monkey/alayer/linux/atspi/AtSpiPoint.java b/linux/src/org/testar/monkey/alayer/linux/atspi/AtSpiPoint.java deleted file mode 100644 index de4d0acdc..000000000 --- a/linux/src/org/testar/monkey/alayer/linux/atspi/AtSpiPoint.java +++ /dev/null @@ -1,121 +0,0 @@ -/*************************************************************************************************** -* -* Copyright (c) 2017 Open Universiteit - www.ou.nl -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, -* this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the copyright holder nor the names of its -* contributors may be used to endorse or promote products derived from -* this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -* POSSIBILITY OF SUCH DAMAGE. -*******************************************************************************************************/ - - -package org.testar.monkey.alayer.linux.atspi; - -import org.bridj.Pointer; - -/** - * Java implementation of the AtSpiPoint structure. - */ -public class AtSpiPoint { - - - - public int x; - public int y; - - - //region Constructors - - - /** - * Default empty constructor. - */ - public AtSpiPoint() { - - } - - - /** - * Creates a new instance of an AtSpiPoint object from a pointer. - * @param pointPtr Pointer to the AtSpiPoint object. - * @return A Java instance of an AtSpiPoint object. - */ - public static AtSpiPoint CreateInstance(long pointPtr) { - - - if (pointPtr == 0) { - return null; - } - - - // Create a new instance. - AtSpiPoint pObj = new AtSpiPoint(); - - - // Fill the instance's properties. - fillInstance(pointPtr, pObj); - - - return pObj; - - } - - - /** - * Fills an AtSpiPoint object's information. - * @param pointPtr Pointer to the AtSpiPoint object. - * @param pObj The Java instance of an AtSpiPoint object. - */ - private static void fillInstance(long pointPtr, AtSpiPoint pObj) { - - - // Fill the properties with the information. - Pointer ptr = Pointer.pointerToAddress(pointPtr, int[].class, null); - - - pObj.x = ptr.getIntAtIndex(0); - pObj.y = ptr.getIntAtIndex(1); - - - } - - - //endregion - - - //region Object overrides - - - /** - * Returns a string representation of an AtSpiPoint object. - * @return Returns a string representation of an AtSpiPoint object. - */ - @Override - public String toString() { - return "(" + x + "," + y + ")"; - } - - - //endregion - - -} diff --git a/linux/src/org/testar/monkey/alayer/linux/atspi/AtSpiRect.java b/linux/src/org/testar/monkey/alayer/linux/atspi/AtSpiRect.java deleted file mode 100644 index 2bc7d486d..000000000 --- a/linux/src/org/testar/monkey/alayer/linux/atspi/AtSpiRect.java +++ /dev/null @@ -1,130 +0,0 @@ -/*************************************************************************************************** -* -* Copyright (c) 2017 Open Universiteit - www.ou.nl -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, -* this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the copyright holder nor the names of its -* contributors may be used to endorse or promote products derived from -* this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -* POSSIBILITY OF SUCH DAMAGE. -*******************************************************************************************************/ - - -package org.testar.monkey.alayer.linux.atspi; - - -import org.bridj.Pointer; - -/** - * Java implementation of the AtSpiRect structure. - */ -public class AtSpiRect { - - - //region Properties - - - public int x = 0; - public int y = 0; - public int width = 0; - public int height = 0; - - - //endregion - - - //region Constructors - - - /** - * Default empty constructor. - */ - public AtSpiRect() { - - } - - - /** - * Creates a new instance of an AtSpiRect object from a pointer. - * @param rectPtr Pointer to the AtSpiRect object. - * @return A Java instance of an AtSpiRect object. - */ - public static AtSpiRect CreateInstance(long rectPtr) { - - - if (rectPtr == 0) { - return null; - } - - - // Create a new instance. - AtSpiRect rObj = new AtSpiRect(); - - - // Fill the instance's properties. - fillInstance(rectPtr, rObj); - - - return rObj; - - } - - - /** - * Fills an AtSpiRect object's information. - * @param rectPtr Pointer to the AtSpiRect object. - * @param rObj The Java instance of an AtSpiRect object. - */ - private static void fillInstance(long rectPtr, AtSpiRect rObj) { - - - // Fill the properties with the information. - Pointer ptr = Pointer.pointerToAddress(rectPtr, int[].class, null); - - - rObj.x = ptr.getIntAtIndex(0); - rObj.y = ptr.getIntAtIndex(1); - rObj.width = ptr.getIntAtIndex(2); - rObj.height = ptr.getIntAtIndex(3); - - } - - - //endregion - - - //region Object overrides - - - /** - * Returns a string representation of an AtSpiRect object. - * @return Returns a string representation of an AtSpiRect object. - */ - @Override - public String toString() { - return "(" + x + "," + y + ") - " + width + "x" + height; - } - - - //endregion - - -} diff --git a/linux/src/org/testar/monkey/alayer/linux/atspi/AtSpiRelation.java b/linux/src/org/testar/monkey/alayer/linux/atspi/AtSpiRelation.java deleted file mode 100644 index 4de8b93e5..000000000 --- a/linux/src/org/testar/monkey/alayer/linux/atspi/AtSpiRelation.java +++ /dev/null @@ -1,208 +0,0 @@ -/*************************************************************************************************** -* -* Copyright (c) 2017 Open Universiteit - www.ou.nl -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, -* this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the copyright holder nor the names of its -* contributors may be used to endorse or promote products derived from -* this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -* POSSIBILITY OF SUCH DAMAGE. -*******************************************************************************************************/ - - -package org.testar.monkey.alayer.linux.atspi; - - -import org.testar.monkey.alayer.linux.atspi.enums.AtSpiRelations; - -import java.util.ArrayList; -import java.util.List; - -/** - * Java implementation of an AtSpiRelation object - An interface via which non-hierarchical relationships are - * indicated. An instance of this interface represents a "one-to-many" correspondance. - */ -public class AtSpiRelation { - - - //region Properties - - - private long _relationPtr; - public long relationPtr() { - return _relationPtr; - } - - - private AtSpiRelations _type; - public AtSpiRelations type() { return AtSpiRelations.values()[LibAtSpi.atspi_relation_get_relation_type(_relationPtr)]; } - - - private int _nrOfTargets; - public int nrOfTargets() { return LibAtSpi.atspi_relation_get_n_targets(_relationPtr); } - - - private List _targets; - public List targets() { return getTargets(this); } - - - //endregion - - - //region Constructors + Initialization - - - /** - * Default empty constructor. - */ - private AtSpiRelation() { - - } - - - /** - * Creates a new instance of an AtSpiRelation object from a pointer. - * @param relationPtr Pointer to the AtSpiRelation object. - * @return A Java instance of an AtSpiRelation object. - */ - public static AtSpiRelation CreateInstance(long relationPtr) { - - - if (relationPtr == 0) { - return null; - } - - - // Create a new instance. - AtSpiRelation rObj = new AtSpiRelation(); - - - // Fill the instance's properties. - rObj._relationPtr = relationPtr; - - - return rObj; - - } - - - /** - * Fills an AtSpiRelation object's information. - * @param relationPtr Pointer to the AtSpiRelation object. - * @param rObj The Java instance of an AtSpiRelation object. - */ - private static void fillInstance(long relationPtr, AtSpiRelation rObj) { - - - // Fill the properties with the information. - rObj._type = AtSpiRelations.values()[LibAtSpi.atspi_relation_get_relation_type(relationPtr)]; - rObj._nrOfTargets = LibAtSpi.atspi_relation_get_n_targets(relationPtr); - - rObj._targets = getTargets(rObj); - - - } - - - //endregion - - - //region Relation functionality - - - /** - * Fills the instance with data for debug purposes. - */ - public void retrieveInformation(boolean fillTargetInfo) { - - fillInstance(_relationPtr, this); - - if (fillTargetInfo) { - for (AtSpiAccessible a : _targets) { - a.retrieveAccessibleInfoNoRelations(); - } - } - - - } - - - /** - * Fills the instance with data for debug purposes. - */ - public void retrieveInformationTree() { - - fillInstance(_relationPtr, this); - - for (AtSpiAccessible a : _targets) { - a.retrieveAccessibleInfoNoRelations(); - } - - } - - - /** - * Creates a list of targets this relation targets. - * @param relation The AtSpiRelation to get the targets for. - * @return A List of AtSpiAccessible targets. - */ - private static List getTargets(AtSpiRelation relation) { - - - ArrayList t = new ArrayList<>(); - - - for (int i = 0; i < relation.nrOfTargets(); i++) { - - AtSpiAccessible a = AtSpiAccessible.CreateInstance(LibAtSpi.atspi_relation_get_target(relation._relationPtr, i)); - - if (a != null) { - t.add(a); - } - - } - - - return t; - - } - - - //endregion - - - //region Object overrides - - - /** - * Returns a string representation of an AtSpiRelation object. - * @return Returns a string representation of an AtSpiRelation object. - */ - @Override - public String toString() { - return "Relation: " + type().toString() + " - Targets: " + nrOfTargets(); - } - - - //endregion - - -} diff --git a/linux/src/org/testar/monkey/alayer/linux/atspi/AtSpiStateSet.java b/linux/src/org/testar/monkey/alayer/linux/atspi/AtSpiStateSet.java deleted file mode 100644 index 2fc777492..000000000 --- a/linux/src/org/testar/monkey/alayer/linux/atspi/AtSpiStateSet.java +++ /dev/null @@ -1,417 +0,0 @@ -/*************************************************************************************************** -* -* Copyright (c) 2017 Open Universiteit - www.ou.nl -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, -* this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the copyright holder nor the names of its -* contributors may be used to endorse or promote products derived from -* this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -* POSSIBILITY OF SUCH DAMAGE. -*******************************************************************************************************/ - - -package org.testar.monkey.alayer.linux.atspi; - - -import org.testar.monkey.alayer.linux.atspi.enums.AtSpiStateTypes; -import org.testar.monkey.alayer.linux.glib.GArray; - -import java.util.ArrayList; -import java.util.List; - - -/** - * Implements wrappers around a bitmap of accessible states for an AtSpiAccessible object. - */ -public class AtSpiStateSet { - - - //region Properties - - - private long _stateSetPtr; - public long stateSetPtr() { - return _stateSetPtr; - } - - - private boolean _invalid; - public boolean isInvalid() { - return LibAtSpi.atspi_state_set_contains(_stateSetPtr, AtSpiStateTypes.Invalid.ordinal()); - } - - - private boolean _active; - public boolean isActive() { - return LibAtSpi.atspi_state_set_contains(_stateSetPtr, AtSpiStateTypes.Active.ordinal()); - } - - - private boolean _armed; - public boolean isArmed() { - return LibAtSpi.atspi_state_set_contains(_stateSetPtr, AtSpiStateTypes.Armed.ordinal()); - } - - - private boolean _busy; - public boolean isBusy() { - return LibAtSpi.atspi_state_set_contains(_stateSetPtr, AtSpiStateTypes.Busy.ordinal()); - } - - - private boolean _checked; - public boolean isChecked() { - return LibAtSpi.atspi_state_set_contains(_stateSetPtr, AtSpiStateTypes.Checked.ordinal()); - } - - - private boolean _collapsed; - public boolean isCollapsed() { - return LibAtSpi.atspi_state_set_contains(_stateSetPtr, AtSpiStateTypes.Collapsed.ordinal()); - } - - - private boolean _defunct; - public boolean isDefunct() { - return LibAtSpi.atspi_state_set_contains(_stateSetPtr, AtSpiStateTypes.Defunct.ordinal()); - } - - - private boolean _editable; - public boolean isEditable() { - return LibAtSpi.atspi_state_set_contains(_stateSetPtr, AtSpiStateTypes.Editable.ordinal()); - } - - - private boolean _enabled; - public boolean isEnabled() { - return LibAtSpi.atspi_state_set_contains(_stateSetPtr, AtSpiStateTypes.Enabled.ordinal()); - } - - - private boolean _expandable; - public boolean isExpandable() { - return LibAtSpi.atspi_state_set_contains(_stateSetPtr, AtSpiStateTypes.Expandable.ordinal()); - } - - - private boolean _expanded; - public boolean isExpanded() { - return LibAtSpi.atspi_state_set_contains(_stateSetPtr, AtSpiStateTypes.Expanded.ordinal()); - } - - - private boolean _focusable; - public boolean isFocusable() { - return LibAtSpi.atspi_state_set_contains(_stateSetPtr, AtSpiStateTypes.Focusable.ordinal()); - } - - - private boolean _focused; - public boolean isFocused() { - return LibAtSpi.atspi_state_set_contains(_stateSetPtr, AtSpiStateTypes.Focused.ordinal()); - } - - - private boolean _hasTooltip; - public boolean hasTooltip() { - return LibAtSpi.atspi_state_set_contains(_stateSetPtr, AtSpiStateTypes.HasTooltip.ordinal()); - } - - - private boolean _horizontal; - public boolean isHorizontal() { - return LibAtSpi.atspi_state_set_contains(_stateSetPtr, AtSpiStateTypes.Horizontal.ordinal()); - } - - - private boolean _iconified; - public boolean isIconified() { - return LibAtSpi.atspi_state_set_contains(_stateSetPtr, AtSpiStateTypes.Iconified.ordinal()); - } - - - private boolean _modal; - public boolean isModal() { - return LibAtSpi.atspi_state_set_contains(_stateSetPtr, AtSpiStateTypes.Modal.ordinal()); - } - - - private boolean _multiLine; - public boolean isMultiLine() { - return LibAtSpi.atspi_state_set_contains(_stateSetPtr, AtSpiStateTypes.MultiLine.ordinal()); - } - - - private boolean _multiSelectable; - public boolean isMultiSelectable() { - return LibAtSpi.atspi_state_set_contains(_stateSetPtr, AtSpiStateTypes.MultiSelectable.ordinal()); - } - - - private boolean _opaque; - public boolean isOpaque() { - return LibAtSpi.atspi_state_set_contains(_stateSetPtr, AtSpiStateTypes.Opaque.ordinal()); - } - - - private boolean _pressed; - public boolean isPressed() { - return LibAtSpi.atspi_state_set_contains(_stateSetPtr, AtSpiStateTypes.Pressed.ordinal()); - } - - - private boolean _resizable; - public boolean isResizable() { - return LibAtSpi.atspi_state_set_contains(_stateSetPtr, AtSpiStateTypes.Resizable.ordinal()); - } - - - private boolean _selectable; - public boolean isSelectable() { - return LibAtSpi.atspi_state_set_contains(_stateSetPtr, AtSpiStateTypes.Selectable.ordinal()); - } - - - private boolean _selected; - public boolean isSelected() { - return LibAtSpi.atspi_state_set_contains(_stateSetPtr, AtSpiStateTypes.Selected.ordinal()); - } - - - private boolean _sensitive; - public boolean isSensitive() { - return LibAtSpi.atspi_state_set_contains(_stateSetPtr, AtSpiStateTypes.Sensitive.ordinal()); - } - - - private boolean _showing; - public boolean isShowing() { - return LibAtSpi.atspi_state_set_contains(_stateSetPtr, AtSpiStateTypes.Showing.ordinal()); - } - - - private boolean _singleLine; - public boolean isSingleLine() {return LibAtSpi.atspi_state_set_contains(_stateSetPtr, AtSpiStateTypes.SingleLine.ordinal()); } - - private boolean _stale; - public boolean isStale() { - return LibAtSpi.atspi_state_set_contains(_stateSetPtr, AtSpiStateTypes.Stale.ordinal()); - } - - - private boolean _transient; - public boolean isTransient() { - return LibAtSpi.atspi_state_set_contains(_stateSetPtr, AtSpiStateTypes.Transient.ordinal()); - } - - - private boolean _vertical; - public boolean isVertical() {return LibAtSpi.atspi_state_set_contains(_stateSetPtr, AtSpiStateTypes.Vertical.ordinal()); } - - private boolean _visible; - public boolean isVisible() { - return LibAtSpi.atspi_state_set_contains(_stateSetPtr, AtSpiStateTypes.Visible.ordinal()); - } - - - private boolean _managesDescendants; - public boolean isManagesDescendants() { - return LibAtSpi.atspi_state_set_contains(_stateSetPtr, AtSpiStateTypes.ManagesDescendants.ordinal()); - } - - - private boolean _indeterminate; - public boolean isIndeterminate() { return LibAtSpi.atspi_state_set_contains(_stateSetPtr, AtSpiStateTypes.Indeterminate.ordinal()); } - - - private boolean _truncated; - public boolean isTruncated() {return LibAtSpi.atspi_state_set_contains(_stateSetPtr, AtSpiStateTypes.Truncated.ordinal()); } - - - private boolean _required; - public boolean isRequired() { - return LibAtSpi.atspi_state_set_contains(_stateSetPtr, AtSpiStateTypes.Required.ordinal()); - } - - - private boolean _invalidEntry; - public boolean isInvalidEntry() { - return LibAtSpi.atspi_state_set_contains(_stateSetPtr, AtSpiStateTypes.InvalidEntry.ordinal()); - } - - - private boolean _supportsAutoCompletion; - public boolean isSupportsAutoCompletion() { return LibAtSpi.atspi_state_set_contains(_stateSetPtr, AtSpiStateTypes.SupportsAutoCompletion.ordinal()); } - - - private boolean _selectableText; - public boolean isSelectableText() { return LibAtSpi.atspi_state_set_contains(_stateSetPtr, AtSpiStateTypes.SelectableText.ordinal()); } - - private boolean _default; - public boolean isDefault() { - return LibAtSpi.atspi_state_set_contains(_stateSetPtr, AtSpiStateTypes.IsDefault.ordinal()); - } - - - private boolean _visited; - public boolean isVisited() { - return LibAtSpi.atspi_state_set_contains(_stateSetPtr, AtSpiStateTypes.Visited.ordinal()); - } - - - /** - * Gets all the states as a list - only the states that are True are returned. - * @return A list of all True states. - */ - public List getStates() { - - - GArray states = GArray.CreateInstance(LibAtSpi.atspi_state_set_get_states(_stateSetPtr), Integer.class); - - - ArrayList statesList = new ArrayList<>(); - - - if (states != null) { - for (int e : states.elements()) { - statesList.add(AtSpiStateTypes.values()[e]); - } - } - - return statesList; - - } - - - //endregion - - - //region Constructors - - - /** - * Default empty constructor. - */ - private AtSpiStateSet() { - - } - - - /** - * Creates a new instance of an AtSpiStateSet object from a pointer. - * @param stateSetPtr Pointer to the AtSpiStateSet object. - * @return A Java instance of an AtSpiStateSet object. - */ - public static AtSpiStateSet CreateInstance(long stateSetPtr) { - - - if (stateSetPtr == 0) { - return null; - } - - - // Create a new instance. - AtSpiStateSet ssObj = new AtSpiStateSet(); - - - // Fill the instance's properties - don't do this as it makes retrieving elements slower. - //fillInstance(stateSetPtr, ssObj); - - - ssObj._stateSetPtr = stateSetPtr; - - - return ssObj; - - } - - - /** - * Fills an AtSpiStateSet object's information. - * @param stateSetPtr Pointer to the AtSpiStateSet object. - * @param ssObj The Java instance of an AtSpiStateSet object. - */ - private static void fillInstance(long stateSetPtr, AtSpiStateSet ssObj) { - - - // Fill the properties with the information. - ssObj._stateSetPtr = stateSetPtr; - - - ssObj._invalid = LibAtSpi.atspi_state_set_contains(stateSetPtr, AtSpiStateTypes.Invalid.ordinal()); - ssObj._active = LibAtSpi.atspi_state_set_contains(stateSetPtr, AtSpiStateTypes.Active.ordinal()); - ssObj._armed = LibAtSpi.atspi_state_set_contains(stateSetPtr, AtSpiStateTypes.Armed.ordinal()); - ssObj._busy = LibAtSpi.atspi_state_set_contains(stateSetPtr, AtSpiStateTypes.Busy.ordinal()); - ssObj._checked = LibAtSpi.atspi_state_set_contains(stateSetPtr, AtSpiStateTypes.Checked.ordinal()); - ssObj._collapsed = LibAtSpi.atspi_state_set_contains(stateSetPtr, AtSpiStateTypes.Collapsed.ordinal()); - ssObj._defunct = LibAtSpi.atspi_state_set_contains(stateSetPtr, AtSpiStateTypes.Defunct.ordinal()); - ssObj._editable = LibAtSpi.atspi_state_set_contains(stateSetPtr, AtSpiStateTypes.Editable.ordinal()); - ssObj._enabled = LibAtSpi.atspi_state_set_contains(stateSetPtr, AtSpiStateTypes.Enabled.ordinal()); - ssObj._expandable = LibAtSpi.atspi_state_set_contains(stateSetPtr, AtSpiStateTypes.Expandable.ordinal()); - ssObj._expanded = LibAtSpi.atspi_state_set_contains(stateSetPtr, AtSpiStateTypes.Expanded.ordinal()); - ssObj._focusable = LibAtSpi.atspi_state_set_contains(stateSetPtr, AtSpiStateTypes.Focusable.ordinal()); - ssObj._focused = LibAtSpi.atspi_state_set_contains(stateSetPtr, AtSpiStateTypes.Focused.ordinal()); - ssObj._hasTooltip = LibAtSpi.atspi_state_set_contains(stateSetPtr, AtSpiStateTypes.HasTooltip.ordinal()); - ssObj._horizontal = LibAtSpi.atspi_state_set_contains(stateSetPtr, AtSpiStateTypes.Horizontal.ordinal()); - ssObj._iconified = LibAtSpi.atspi_state_set_contains(stateSetPtr, AtSpiStateTypes.Iconified.ordinal()); - ssObj._modal = LibAtSpi.atspi_state_set_contains(stateSetPtr, AtSpiStateTypes.Modal.ordinal()); - ssObj._multiLine = LibAtSpi.atspi_state_set_contains(stateSetPtr, AtSpiStateTypes.MultiLine.ordinal()); - ssObj._multiSelectable = LibAtSpi.atspi_state_set_contains(stateSetPtr, AtSpiStateTypes.MultiSelectable.ordinal()); - ssObj._opaque = LibAtSpi.atspi_state_set_contains(stateSetPtr, AtSpiStateTypes.Opaque.ordinal()); - ssObj._pressed = LibAtSpi.atspi_state_set_contains(stateSetPtr, AtSpiStateTypes.Pressed.ordinal()); - ssObj._resizable = LibAtSpi.atspi_state_set_contains(stateSetPtr, AtSpiStateTypes.Resizable.ordinal()); - ssObj._selectable = LibAtSpi.atspi_state_set_contains(stateSetPtr, AtSpiStateTypes.Selectable.ordinal()); - ssObj._selected = LibAtSpi.atspi_state_set_contains(stateSetPtr, AtSpiStateTypes.Selected.ordinal()); - ssObj._sensitive = LibAtSpi.atspi_state_set_contains(stateSetPtr, AtSpiStateTypes.Sensitive.ordinal()); - ssObj._showing = LibAtSpi.atspi_state_set_contains(stateSetPtr, AtSpiStateTypes.Showing.ordinal()); - ssObj._singleLine = LibAtSpi.atspi_state_set_contains(stateSetPtr, AtSpiStateTypes.SingleLine.ordinal()); - ssObj._stale = LibAtSpi.atspi_state_set_contains(stateSetPtr, AtSpiStateTypes.Stale.ordinal()); - ssObj._transient = LibAtSpi.atspi_state_set_contains(stateSetPtr, AtSpiStateTypes.Transient.ordinal()); - ssObj._vertical = LibAtSpi.atspi_state_set_contains(stateSetPtr, AtSpiStateTypes.Vertical.ordinal()); - ssObj._visible = LibAtSpi.atspi_state_set_contains(stateSetPtr, AtSpiStateTypes.Visible.ordinal()); - ssObj._managesDescendants = LibAtSpi.atspi_state_set_contains(stateSetPtr, AtSpiStateTypes.ManagesDescendants.ordinal()); - ssObj._indeterminate = LibAtSpi.atspi_state_set_contains(stateSetPtr, AtSpiStateTypes.Indeterminate.ordinal()); - ssObj._truncated = LibAtSpi.atspi_state_set_contains(stateSetPtr, AtSpiStateTypes.Truncated.ordinal()); - ssObj._required = LibAtSpi.atspi_state_set_contains(stateSetPtr, AtSpiStateTypes.Required.ordinal()); - ssObj._invalidEntry = LibAtSpi.atspi_state_set_contains(stateSetPtr, AtSpiStateTypes.InvalidEntry.ordinal()); - ssObj._supportsAutoCompletion = LibAtSpi.atspi_state_set_contains(stateSetPtr, AtSpiStateTypes.SupportsAutoCompletion.ordinal()); - ssObj._selectableText = LibAtSpi.atspi_state_set_contains(stateSetPtr, AtSpiStateTypes.SelectableText.ordinal()); - ssObj._default = LibAtSpi.atspi_state_set_contains(stateSetPtr, AtSpiStateTypes.IsDefault.ordinal()); - ssObj._visited = LibAtSpi.atspi_state_set_contains(stateSetPtr, AtSpiStateTypes.Visited.ordinal()); - - - } - - - //endregion - - - /** - * Fills this object with full state information -- intended for testing purposes: complete view of the object's state. - */ - public void retrieveStates() { - fillInstance(_stateSetPtr, this); - } - - - -} diff --git a/linux/src/org/testar/monkey/alayer/linux/atspi/AtSpiValue.java b/linux/src/org/testar/monkey/alayer/linux/atspi/AtSpiValue.java deleted file mode 100644 index 244ef71e9..000000000 --- a/linux/src/org/testar/monkey/alayer/linux/atspi/AtSpiValue.java +++ /dev/null @@ -1,152 +0,0 @@ -/*************************************************************************************************** -* -* Copyright (c) 2017 Open Universiteit - www.ou.nl -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, -* this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the copyright holder nor the names of its -* contributors may be used to endorse or promote products derived from -* this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -* POSSIBILITY OF SUCH DAMAGE. -*******************************************************************************************************/ - - -package org.testar.monkey.alayer.linux.atspi; - - -/** - * Java implementation of an AtSpiValue object - An interface supporting a one-dimensional scalar to be modified, - * or which reflects its value. If STATE_EDITABLE is not present, the value is treated as "read only". - */ -public class AtSpiValue { - - - //region Properties - - - private long _valuePtr; - public long valuePtr() { - return _valuePtr; - } - - - private double _minimumValue; - public double minimumValue() { return LibAtSpi.atspi_value_get_minimum_value(_valuePtr, 0); } - - - private double _currentValue; - public double currentValue() { return LibAtSpi.atspi_value_get_current_value(_valuePtr, 0); } - - - private double _maximumValue; - public double maximumValue() { return LibAtSpi.atspi_value_get_maximum_value(_valuePtr, 0); } - - - //endregion - - - //region Constructors + Initialization - - - /** - * Default empty constructor. - */ - private AtSpiValue() { - - } - - - /** - * Creates a new instance of an AtSpiValue object from a pointer. - * @param valuePtr Pointer to the AtSpiValue object. - * @return A Java instance of an AtSpiValue object. - */ - public static AtSpiValue CreateInstance(long valuePtr) { - - - if (valuePtr == 0) { - return null; - } - - - // Create a new instance. - AtSpiValue cObj = new AtSpiValue(); - - - // Fill the instance's properties. - cObj._valuePtr = valuePtr; - - - return cObj; - - } - - - /** - * Fills an AtSpiValue object's information. - * @param valuePtr Pointer to the AtSpiValue object. - * @param vObj The Java instance of an AtSpiValue object. - */ - private static void fillInstance(long valuePtr, AtSpiValue vObj) { - - - // Fill the properties with the information. - vObj._minimumValue = LibAtSpi.atspi_value_get_minimum_value(valuePtr, 0); - vObj._currentValue = LibAtSpi.atspi_value_get_current_value(valuePtr, 0); - vObj._maximumValue = LibAtSpi.atspi_value_get_maximum_value(valuePtr, 0); - - - } - - - //endregion - - - //region Value functionality - - - /** - * Fills the instance with data for debug purposes. - */ - public void retrieveInformation() { - fillInstance(_valuePtr, this); - } - - - //endregion - - - //region Object overrides - - - /** - * Returns a string representation of an AtSpiValue object. - * @return Returns a string representation of an AtSpiValue object. - */ - @Override - public String toString() { - return "Value: " + currentValue() + " - MinValue: " + minimumValue() + " - MaxValue: " + maximumValue(); - } - - - //endregion - - -} diff --git a/linux/src/org/testar/monkey/alayer/linux/atspi/LibAtSpi.java b/linux/src/org/testar/monkey/alayer/linux/atspi/LibAtSpi.java deleted file mode 100644 index 096a85f36..000000000 --- a/linux/src/org/testar/monkey/alayer/linux/atspi/LibAtSpi.java +++ /dev/null @@ -1,540 +0,0 @@ -/*************************************************************************************************** -* -* Copyright (c) 2017 Open Universiteit - www.ou.nl -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, -* this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the copyright holder nor the names of its -* contributors may be used to endorse or promote products derived from -* this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -* POSSIBILITY OF SUCH DAMAGE. -*******************************************************************************************************/ - - -package org.testar.monkey.alayer.linux.atspi; - - -import org.bridj.BridJ; -import org.bridj.Pointer; -import org.bridj.ann.Library; - -import java.io.IOException; - - -/** - * AT-SPI implementation. - */ -@Library("libatspi") -public class LibAtSpi { - - - static{ - try { - BridJ.getNativeLibrary("libatspi"); - } catch (IOException e) { - e.printStackTrace(); - } - BridJ.register(); - } - - - - //*** Registry ***\\ - - - /** - * Gets the number of virtual desktops. NOTE: multiple virtual desktops are not implemented yet; as a consequence, this function always returns 1. - * @return The number of active virtual desktops. - */ - public static native int atspi_get_desktop_count(); - - - /** - * Gets the virtual desktop indicated by index i . NOTE: currently multiple virtual desktops are not implemented; as - * a consequence, any i value different from 0 will not return a virtual desktop - instead it will return NULL. - * @param desktopIndex Index indicating which of the accessible desktops is to be returned. - * @return Returns a pointer to the i -th virtual desktop's AtspiAccessible representation. - */ - public static native long atspi_get_desktop(int desktopIndex); - - - /** - * Gets the list of virtual desktops. On return, list will point to a newly-created, NULL terminated array of virtual desktop pointers. - * It is the responsibility of the caller to free this array when it is no longer needed. NOTE: currently multiple virtual desktops - * are not implemented; this implementation always returns a Garray with a single AtspiAccessible desktop. - * @return Returns a GArray of desktops (Type: AtspiAccessible*). - */ - public static native long atspi_get_desktop_list(); - - - - //*** AtspiAccessible ***\\ - - - /** - * Gets the name of an AtspiAccessible object. - * @param accessiblePtr A pointer to the AtspiAccessible object on which to operate. - * @param errorPtrToPtr A pointer-to-pointer where an GError can be stored. - * @return Returns a UTF-8 string indicating the name of the AtspiAccessible object or NULL on exception. - */ - public static native Pointer atspi_accessible_get_name(long accessiblePtr, long errorPtrToPtr); - - - /** - * Gets the description of an AtspiAccessible object. - * @param accessiblePtr A pointer to the AtspiAccessible object on which to operate. - * @param errorPtrToPtr A pointer-to-pointer where an GError can be stored. - * @return Returns a UTF-8 string describing the AtspiAccessible object or NULL on exception. - */ - public static native Pointer atspi_accessible_get_description(long accessiblePtr, long errorPtrToPtr); - - - /** - * Gets (a pointer to) an AtspiAccessible object's parent container. - * @param accessiblePtr A pointer to the AtspiAccessible object on which to operate. - * @param errorPtrToPtr A pointer-to-pointer where an GError can be stored. - * @return Returns a pointer to the AtspiAccessible object which contains the given AtspiAccessible instance, - * or NULL if the obj has no parent container. - */ - public static native long atspi_accessible_get_parent(long accessiblePtr, long errorPtrToPtr); - - - /** - * Gets the number of children contained by an AtspiAccessible object. - * @param accessiblePtr A pointer to the AtspiAccessible object on which to operate. - * @param errorPtrToPtr A pointer-to-pointer where an GError can be stored. - * @return Returns a the number of AtspiAccessible children contained by an AtspiAccessible object or -1 on exception. - */ - public static native int atspi_accessible_get_child_count(long accessiblePtr, long errorPtrToPtr); - - - /** - * Gets a UTF-8 string corresponding to the name of the role played by an object. This method will return useful values for - * roles that fall outside the enumeration used in atspi_accessible_get_role(). - * @param accessiblePtr A pointer to the AtspiAccessible object on which to operate. - * @param childIndex The index of the child to get. - * @param errorPtrToPtr A pointer-to-pointer where an GError can be stored. - * @return Returns a UTF-8 string specifying the type of UI role played by an AtspiAccessible object. - */ - public static native long atspi_accessible_get_child_at_index(long accessiblePtr, int childIndex, long errorPtrToPtr); - - - /** - * Gets the index of an AtspiAccessible object within its parent's AtspiAccessible children list. - * @param accessiblePtr A pointer to the AtspiAccessible object on which to operate. - * @param errorPtrToPtr A pointer-to-pointer where an GError can be stored. - * @return Returns an int indicating the index of the AtspiAccessible object in its parent, - * or -1 if obj has no containing parent or on exception. - */ - public static native int atspi_accessible_get_index_in_parent(long accessiblePtr, long errorPtrToPtr); - - - /** - * Gets the set of AtspiRelation objects which describes this AtspiAccessible object's relationships with other - * AtspiAccessible objects. - * @param accessiblePtr A pointer to the AtspiAccessible object on which to operate. - * @param errorPtrToPtr A pointer-to-pointer where an GError can be stored. - * @return Returns a (pointer to a) GArray of AtspiRelation pointers or NULL on exception. - */ - public static native long atspi_accessible_get_relation_set(long accessiblePtr, long errorPtrToPtr); - - - /** - * Gets the UI role played by an AtspiAccessible object. This role's name can be obtained via atspi_accessible_get_role_name(). - * @param accessiblePtr A pointer to the AtspiAccessible object on which to operate. - * @param errorPtrToPtr A pointer-to-pointer where an GError can be stored. - * @return Returns the AtspiRole of an AtspiAccessible object. - */ - public static native int atspi_accessible_get_role(long accessiblePtr, long errorPtrToPtr); - - - /** - * Gets a UTF-8 string corresponding to the name of the role played by an object. This method will return useful values for - * roles that fall outside the enumeration used in atspi_accessible_get_role(). - * @param accessiblePtr A pointer to the AtspiAccessible object on which to operate. - * @param errorPtrToPtr A pointer-to-pointer where an GError can be stored. - * @return Returns a UTF-8 string specifying the type of UI role played by an AtspiAccessible object. - */ - public static native Pointer atspi_accessible_get_role_name(long accessiblePtr, long errorPtrToPtr); - - - /** - * Gets the states currently held by an object. - * @param accessiblePtr A pointer to the AtspiAccessible object on which to operate. - * @return Returns a pointer to an AtspiStateSet representing an object's current state set. - */ - public static native long atspi_accessible_get_state_set(long accessiblePtr); - - - /** - * Gets the AttributeSet representing any assigned name-value pair attributes or annotations for this object. - * For typographic, textual, or textually-semantic attributes, see atspi_text_get_attributes instead. - * @param accessiblePtr A pointer to the AtspiAccessible object on which to operate. - * @param errorPtrToPtr A pointer-to-pointer where an GError can be stored. - * @return Returns the name-value-pair attributes assigned to this object. - */ - public static native long atspi_accessible_get_attributes(long accessiblePtr, long errorPtrToPtr); - - - /** - * Gets a GArray representing any assigned name-value pair attributes or annotations for this object. - * For typographic, textual, or textually-semantic attributes, see atspi_text_get_attributes_as_array instead. - * @param accessiblePtr A pointer to the AtspiAccessible object on which to operate. - * @param errorPtrToPtr A pointer-to-pointer where an GError can be stored. - * @return Returns the name-value-pair attributes assigned to this object. - */ - public static native long atspi_accessible_get_attributes_as_array(long accessiblePtr, long errorPtrToPtr); - - - /** - * Gets the toolkit name for an AtspiAccessible object. Only works on application root objects. - * @param accessiblePtr A pointer to the AtspiAccessible object on which to operate. - * @param errorPtrToPtr A pointer-to-pointer where an GError can be stored. - * @return Returns a UTF-8 string indicating the toolkit name for the AtspiAccessible object or NULL on exception. - */ - public static native Pointer atspi_accessible_get_toolkit_name(long accessiblePtr, long errorPtrToPtr); - - - /** - * Gets the toolkit version for an AtspiAccessible object. Only works on application root objects. - * @param accessiblePtr A pointer to the AtspiAccessible object on which to operate. - * @param errorPtrToPtr A pointer-to-pointer where an GError can be stored. - * @return Returns a UTF-8 string indicating the toolkit version for the AtspiAccessible object or NULL on exception. - */ - public static native Pointer atspi_accessible_get_toolkit_version(long accessiblePtr, long errorPtrToPtr); - - - /** - * Gets the AtspiCollection interface for an AtspiAccessible. - * @param accessiblePtr A pointer to the AtspiAccessible object on which to operate. - * @return Returns a pointer to an AtspiCollection interface instance, or NULL if obj does - * not implement AtspiCollection. - */ - public static native long atspi_accessible_get_collection_iface(long accessiblePtr); - - - /** - * Gets the AtspiComponent interface for an AtspiAccessible. - * @param accessiblePtr A pointer to the AtspiAccessible object on which to operate. - * @return a pointer to an AtspiComponent interface instance, or NULL if obj does not implement AtspiComponent. - */ - public static native long atspi_accessible_get_component_iface(long accessiblePtr); - - - /** - * Gets the AtspiAction interface for an AtspiAccessible. - * @param accessiblePtr A pointer to the AtspiAccessible object on which to operate. - * @return Returns a pointer to an AtspiAction interface instance, or NULL if obj does not implement AtspiAction. - */ - public static native long atspi_accessible_get_action_iface(long accessiblePtr); - - - /** - * Gets the AtspiTable interface for an AtspiAccessible. - * @param accessiblePtr A pointer to the AtspiAccessible object on which to operate. - * @return Returns a pointer to an AtspiValue interface instance, or NULL if obj does not implement AtspiValue. - */ - public static native long atspi_accessible_get_value_iface(long accessiblePtr); - - - /** - * A set of pointers to strings describing all interfaces supported by an AtspiAccessible. - * @param accessiblePtr A pointer to the AtspiAccessible object on which to operate. - * @return A GArray of strings describing the interfaces supported by the object. - * Interfaces are denoted in short-hand (i.e. "Component", "Text" etc.). - */ - public static native long atspi_accessible_get_interfaces(long accessiblePtr); - - - - //*** AtSpi StateSet ***\\ - - - /** - * Determines whether a given AtspiStateSet includes a given state; that is, whether state is true - * for the set in question. - * @param setPtr A pointer to the AtspiStateSet object on which to operate. - * @param state An AtspiStateType for which the specified AtspiStateSet will be queried. - * @return TRUE if state is true/included in the given AtspiStateSet, otherwise FALSE. - */ - public static native boolean atspi_state_set_contains(long setPtr, int state); - - - /** - * Returns the states in an AtspiStateSet as (a pointer to) an array. - * @param setPtr A pointer to the AtspiStateSet object on which to operate. - * @return A GArray of state types representing the current state. - */ - public static native long atspi_state_set_get_states(long setPtr); - - - - //*** AtSpiAction ***\\ - - - /** - * Get the number of actions invokable on an AtspiAction implementor. - * @param actionPtr A pointer to the AtSpiAction object on which to operate. - * @param errorPtrToPtr A pointer-to-pointer where an GError can be stored. - * @return Returns an integer indicating the number of invocable actions. - */ - public static native int atspi_action_get_n_actions(long actionPtr, long errorPtrToPtr); - - - /** - * Get the description of 'i -th' action invocable on an object implementing AtspiAction. - * @param actionPtr A pointer to the AtSpiAction object on which to operate. - * @param actionIndex An integer indicating which action to query. - * @param errorPtrToPtr A pointer-to-pointer where an GError can be stored. - * @return Returns a UTF-8 string describing the 'i -th' invocable action. - */ - public static native Pointer atspi_action_get_action_description(long actionPtr, int actionIndex, long errorPtrToPtr); - - - /** - * Get the description of 'i -th' action invocable on an object implementing AtspiAction. - * @param actionPtr A pointer to the AtSpiAction object on which to operate. - * @param actionIndex An integer indicating which action to query. - * @param errorPtrToPtr A pointer-to-pointer where an GError can be stored. - * @return Returns a UTF-8 string describing the 'i -th' invocable action. - */ - public static native Pointer atspi_action_get_key_binding(long actionPtr, int actionIndex, long errorPtrToPtr); - - - /** - * Get the keybindings for the i -th action invocable on an object implementing AtspiAction, if any are defined. - * The keybindings string format is as follows: there are multiple parts to a keybinding string (typically 3). They - * are delimited with ";". The first is the action's keybinding which is usable if the object implementing the action - * is currently posted to the screen, e.g. if a menu is posted then these keybindings for the corresponding - * menu-items are available. The second keybinding substring is the full key sequence necessary to post the - * action's widget and activate it, e.g. for a menu item such as "File->Open" it would both post the menu and - * activate the item. Thus the second keybinding string is available during the lifetime of the containing - * toplevel window as a whole, whereas the first keybinding string only works while the object implementing - * AtkAction is posted. The third (and optional) keybinding string is the "keyboard shortcut" which invokes - * the action without posting any menus. Meta-keys are indicated by the conventional strings "<Control>", - * "<Alt>", "<hift>", "<Mod2>", etc. (we use the same string as gtk_accelerator_name() in gtk+-2.X. - * @param actionPtr A pointer to the AtSpiAction object on which to operate. - * @param actionIndex An integer indicating which action to query. - * @param errorPtrToPtr A pointer-to-pointer where an GError can be stored. - * @return Returns a UTF-8 string which can be parsed to determine the i -th invocable action's keybindings. - */ - public static native Pointer atspi_action_get_action_name(long actionPtr, int actionIndex, long errorPtrToPtr); - - - /** - * Invoke the action indicated by index. - * @param actionPtr A pointer to the AtSpiAction object on which to operate. - * @param actionIndex An integer indicating which action to query. - * @param errorPtrToPtr A pointer-to-pointer where an GError can be stored. - * @return Returns TRUE if the action is successfully invoked, otherwise FALSE. - */ - public static native boolean atspi_action_do_action(long actionPtr, int actionIndex, long errorPtrToPtr); - - - - //*** AtSpiComponent ***\\ - - - /** - * Queries which layer the component is painted into, to help determine its visibility in terms of stacking order. - * @param componentPtr A pointer to the AtSpiComponent object on which to operate. - * @param coordType Type of the coordinate system to use: Screen or Window. - * @param errorPtrToPtr A pointer-to-pointer where an GError can be stored. - * @return Returns the AtspiComponentLayer into which this component is painted. - */ - public static native long atspi_component_get_extents(long componentPtr, int coordType, long errorPtrToPtr); - - - /** - * Gets the minimum x and y coordinates of the specified AtspiComponent. - * @param componentPtr A pointer to the AtSpiComponent object on which to operate. - * @param coordType Type of the coordinate system to use: Screen or Window. - * @param errorPtrToPtr A pointer-to-pointer where an GError can be stored. - * @return Returns an AtspiPoint giving the obj's position. - */ - public static native long atspi_component_get_position(long componentPtr, int coordType, long errorPtrToPtr); - - - /** - * Gets the size of the specified AtspiComponent. - * @param componentPtr A pointer to the AtSpiComponent object on which to operate. - * @param errorPtrToPtr A pointer-to-pointer where an GError can be stored. - * @return Returns an AtspiPoint giving the obj's size. - */ - public static native long atspi_component_get_size(long componentPtr, long errorPtrToPtr); - - - /** - * Queries which layer the component is painted into, to help determine its visibility in terms of stacking order. - * @param componentPtr A pointer to the AtSpiComponent object on which to operate. - * @param errorPtrToPtr A pointer-to-pointer where an GError can be stored. - * @return Returns the AtspiComponentLayer into which this component is painted. - */ - public static native int atspi_component_get_layer(long componentPtr, long errorPtrToPtr); - - - /** - * Queries the z stacking order of a component which is in the MDI or window layer - * (Bigger z-order numbers mean nearer the top). - * @param componentPtr A pointer to the AtSpiComponent object on which to operate. - * @param errorPtrToPtr A pointer-to-pointer where an GError can be stored. - * @return Returns a short indicating the stacking order of the component in the MDI layer, - * or -1 if the component is not in the MDI layer. - */ - public static native short atspi_component_get_mdi_z_order(long componentPtr, long errorPtrToPtr); - - - /** - * Attempts to set the keyboard input focus to the specified AtspiComponent. - * @param componentPtr A pointer to the AtSpiComponent object on which to operate. - * @param errorPtrToPtr A pointer-to-pointer where an GError can be stored. - * @return Returns TRUE if successful, FALSE otherwise. - */ - public static native boolean atspi_component_grab_focus(long componentPtr, long errorPtrToPtr); - - - - //*** AtspiValue ***\\ - - - /** - * Gets the minimum allowed value for an AtspiValue. - * @param valuePtr A pointer to the AtSpiValue object on which to operate. - * @param errorPtrToPtr A pointer-to-pointer where an GError can be stored. - * @return Returns the minimum allowed value for this object. - */ - public static native double atspi_value_get_minimum_value(long valuePtr, long errorPtrToPtr); - - - /** - * Gets the current value for an AtspiValue. - * @param valuePtr A pointer to the AtSpiValue object on which to operate. - * @param errorPtrToPtr A pointer-to-pointer where an GError can be stored. - * @return Returns the current value for this object. - */ - public static native double atspi_value_get_current_value(long valuePtr, long errorPtrToPtr); - - - /** - * Gets the maximum allowed value for an AtspiValue. - * @param valuePtr A pointer to the AtSpiValue object on which to operate. - * @param errorPtrToPtr A pointer-to-pointer where an GError can be stored. - * @return Returns the maximum allowed value for this object. - */ - public static native double atspi_value_get_maximum_value(long valuePtr, long errorPtrToPtr); - - - - //*** AtspiRelation ***\\ - - - /** - * Gets the type of relationship represented by an AtspiRelation. - * @param relationPtr A pointer to the AtSpiRelation object on which to operate. - * @return Returns an AtspiRelationType indicating the type of relation encapsulated in this AtspiRelation object. - */ - public static native int atspi_relation_get_relation_type(long relationPtr); - - - /** - * Gets the number of objects which this relationship has as its target objects (the subject is the - * AtspiAccessible from which this AtspiRelation originated). - * @param relationPtr A pointer to the AtSpiRelation object on which to operate. - * @return Returns a int indicating how many target objects which the originating AtspiAccessible object - * has the AtspiRelation relationship with. - */ - public static native int atspi_relation_get_n_targets(long relationPtr); - - - /** - * Gets the i -th target of a specified AtspiRelation relationship. - * @param relationPtr A pointer to the AtSpiRelation object on which to operate. - * @param relationIndex A (zero-index) int indicating which (of possibly several) target is requested. - * @return Returns an AtspiAccessible which is the i -th object with which the originating AtspiAccessible has - * relationship specified in the AtspiRelation object. - */ - public static native long atspi_relation_get_target(long relationPtr, int relationIndex); - - - - //*** gLib is a part of the libatspi library!!! ***\\ - - - - //*** GArray ***\\ - - - /** - * Gets the size of the elements in array. - * @param arrayPtr A pointer to the GArray. - * @return Size of each element, in bytes. - */ - public static native int g_array_get_element_size(long arrayPtr); - - - - //*** GList ***\\ - - - /** - * Frees all of the memory used by a GList. The freed elements are returned to the slice allocator. If list - * elements contain dynamically-allocated memory, you should either use g_list_free_full() or free them - * manually first. - * @param listPtr A pointer to the GList. - */ - public static native void g_list_free(long listPtr); - - - /** - * Gets the number of elements in a GList. This function iterates over the whole list to count - * its elements. Use a GQueue instead of a GList if you regularly need the number of items. To check whether - * the list is non-empty, it is faster to check list against NULL. - * @param listPtr A pointer to the GList. - * @return Returns the number of elements in the GList - */ - public static native int g_list_length(long listPtr); - - - - - //*** GHashTable ***\\ - - - /** - * Returns the number of elements contained in the GHashTable. - * @param hashTablePtr A pointer to the GHashTable. - * @return Returns the number of key/value pairs in the GHashTable. - */ - public static native int g_hash_table_size(long hashTablePtr); - - - /** - * Retrieves every key inside hash_table . The returned data is valid until changes to the hash release those keys. - * This iterates over every entry in the hash table to build its return value. To iterate over the entries in a - * GHashTable more efficiently, use a GHashTableIter. - * @param hashTablePtr A pointer to the GHashTable. - * @return Returns (a pointer to) a GList containing all the keys inside the hash table. The content of the list is - * owned by the hash table and should not be modified or freed. Use g_list_free() when done using the list. - */ - public static native long g_hash_table_get_keys(long hashTablePtr); - - - -} diff --git a/linux/src/org/testar/monkey/alayer/linux/atspi/TreeWalker.java b/linux/src/org/testar/monkey/alayer/linux/atspi/TreeWalker.java deleted file mode 100644 index 917a52913..000000000 --- a/linux/src/org/testar/monkey/alayer/linux/atspi/TreeWalker.java +++ /dev/null @@ -1,576 +0,0 @@ -/*************************************************************************************************** -* -* Copyright (c) 2017 Open Universiteit - www.ou.nl -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, -* this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the copyright holder nor the names of its -* contributors may be used to endorse or promote products derived from -* this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -* POSSIBILITY OF SUCH DAMAGE. -*******************************************************************************************************/ - - -package org.testar.monkey.alayer.linux.atspi; - - -import org.testar.monkey.alayer.linux.atspi.enums.AtSpiRoles; -import org.testar.monkey.alayer.linux.atspi.enums.AtSpiStateTypes; -import org.testar.monkey.alayer.linux.util.xdotools; - -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; - - -/** - * Class to help with creating and traversing AtSpi trees/ nodes. - */ -public class TreeWalker { - - - /** - * Gets AtSpiAccessible nodes representing an application with the supplied name. - * @param applicationName The name of the application to get the AtSpiAccessible nodes for. - * @return A list of AtSpiAccessible nodes representing applications with the supplied name. - */ - public static List getApplicationNodes(String applicationName) { - return getApplicationNodes(applicationName, false); - } - - - /** - * Gets AtSpiAccessible nodes representing an application with the supplied name. - * @param applicationName The name of the application to get the AtSpiAccessible nodes for. - * @param createTree If True, the node will be completely filled with information. - * @return A list of AtSpiAccessible nodes representing applications with the supplied name. - */ - public static List getApplicationNodes(String applicationName, boolean createTree) { - - - // The list that will hold the requested application nodes. - ArrayList applicationNodes = new ArrayList<>(); - - - // Get a pointer to the desktop accessible object. - long desktopPointer = LibAtSpi.atspi_get_desktop(0); - - - // Create an AtSpiAccessible object from the pointer. - AtSpiAccessible desktopNode = AtSpiAccessible.CreateInstance(desktopPointer); - - - if (applicationName.endsWith(".jar")) { - applicationName = applicationName.replace(".jar", ""); - } - - - if (desktopNode != null) { - - // Each child of the desktop should be an application - still check to be sure. - // All nodes with the name corresponding to the requested name will be returned. - for (AtSpiAccessible child : desktopNode.children()) { - - if (child.role() == AtSpiRoles.Application && Objects.equals(child.name().toLowerCase(), applicationName.toLowerCase())) { - applicationNodes.add(child); - } - - } - - } - - - // Get all children for each application node - making it the root of a tree. - if (createTree) { - for (AtSpiAccessible appplicationNode : applicationNodes) { - appplicationNode.retrieveAccessibleInfoTree(); - } - } - - - return applicationNodes; - - - } - - - /** - * Finds the application node belonging to the application with the supplied application name and PID. - * @param applicationName The name of the application to look for. - * @param pid The PID of the application to look for. - * @return The application node belonging to the application with the supplied applicaiton name and PID. - */ - public static AtSpiAccessible findApplicationNode(String applicationName, long pid) { - return findApplicationNode(getApplicationNodes(applicationName), pid); - } - - - /** - * Finds the application node belonging to the application with the supplied PID. - * @param applicationNodes A list of application nodes (most likely from likely named application) that should - * contain the application to which the supplied PID belongs. - * @param pid The PID of the application to look for. - * @return The application node belonging to the application with the supplied PID. - */ - public static AtSpiAccessible findApplicationNode(List applicationNodes, long pid) { - - - if (applicationNodes == null) { - throw new IllegalArgumentException("The application nodes list cannot be null."); - } - - - if (pid <= 0) { - throw new IllegalArgumentException("The PID of an applicaiton cannot be equal to or less than zero."); - } - - - - if (applicationNodes.size() == 0) { - System.out.println("Could not find a single running application by the supplied name."); - } - - - // Activate each application through AT-SPI and find the PID for each active application through xdotool. - // Once verified that the node activated the instance of the application launched by us - stop. - for (AtSpiAccessible application : applicationNodes) { - - - // Activate application. - if (TreeWalker.activateApplication(application)) { - - // Short pause to give the application time to activate. - try { - Thread.sleep(200); - } catch (InterruptedException e) { - e.printStackTrace(); - } - - - // Retrieve PID through xdotool. - int activePID = xdotools.getPIDFromActiveWindow(); - - - // Check if the PID matches the PID of the process we're supposed to activate. - if (pid == activePID) { - return application; - } - - - } else { - System.out.println("Cannot activate an application with the same name - continuing loop..."); - } - - - } - - - System.out.println("Cannot find an application node in the list belonging to an application with PID '" + pid + "'."); - return null; - - - } - - - /** - * Retrieves the application that is currently active from the supplied list of application nodes. - * @param applicationNodes A list of AtSpiAccessible nodes representing an application (most likely with the same name). - * @return The application that is currently active. - */ - public static AtSpiAccessible getActiveApplicationNode(List applicationNodes) { - - - if (applicationNodes == null) { - throw new IllegalArgumentException("The application nodes list argument cannot be null."); - } - - - for (AtSpiAccessible application : applicationNodes) { - if (isApplicationActive(application)) { - // There can only be one active application at the same time... - return application; - } - } - - - // Active application is not one of the supplied applications. - return null; - - - } - - - /** - * Activates an application by focusing a focusable element. - * @param applicationNode The AtSpiAccessible application node of the application to activate. - * @return True if activating is successful; False otherwise. - */ - public static boolean activateApplication(AtSpiAccessible applicationNode) { - - - if (applicationNode.role() != AtSpiRoles.Application) { - throw new IllegalArgumentException("The application node should be an AtSpiAccessible with role 'Application'."); - } - - - // Find a child element that can be focused. - AtSpiAccessible focusableNode = findFocusable(applicationNode); - - - if (focusableNode == null) { - System.out.println("Could not find a focusable application element node for '" + applicationNode.name() + "'."); - return false; - } - - if (focusableNode.component() == null) { - System.out.println("The component of the a focusable application element node is null for '" + applicationNode.name() + "'."); - return false; - } - - - // Focus the element and with it activate the application. - return focusableNode.component().grabFocus(); - - - } - - - /** - * Determines whether an application is active. - * @param applicationNode The AtSpiAccessible application node of the application to check whether it is active or not. - * @return True if the application is active; False otherwise. - */ - public static boolean isApplicationActive(AtSpiAccessible applicationNode) { - - - if (applicationNode.role() != AtSpiRoles.Application) { - throw new IllegalArgumentException("The application node should be an AtSpiAccessible with role 'Application'."); - } - - - // Check the children - Check all for the frame role and active state. - for (AtSpiAccessible child : applicationNode.children()) { - if (child.role() == AtSpiRoles.Frame && child.states().isActive()) { - return true; - } - } - - return false; - - - } - - - /** - * Determines if an application has modal windows open. - * @param applicationNode The application node of the application to check modal windows for. - * @return True if the application has modal windows; False otherwise. - */ - public static boolean hasApplicationModalDialogs(AtSpiAccessible applicationNode) { - - - if (applicationNode.role() != AtSpiRoles.Application) { - throw new IllegalArgumentException("The application node should be an AtSpiAccessible with role 'Application'."); - } - - - // Check the children - this could be frames, windows or modal dialogs - check if one is of them is modal. - for (AtSpiAccessible child : applicationNode.children()) { - - AtSpiStateSet childState = child.states(); - - if (childState != null && childState.isModal()) { - return true; - } - - } - - - return false; - - - } - - - /** - * Retrieves a list of non-modal application child nodes - it will only process the direct children of the - * application node, i.e. the frame, window, dialog nodes that can be modal. - * @param applicationNode The application node of the application to get non-modal windows for. - * @return A list of non-modal windows for an application. - */ - public static List getNonModalApplicationChildNodes(AtSpiAccessible applicationNode) { - - - if (applicationNode.role() != AtSpiRoles.Application) { - throw new IllegalArgumentException("The application node should be an AtSpiAccessible with role 'Application'."); - } - - - ArrayList nonModals = new ArrayList<>(); - - - // Check the children - this could be frames, windows or modal dialogs - add the non-modals to the list. - for (AtSpiAccessible child : applicationNode.children()) { - - AtSpiStateSet childState = child.states(); - - if (childState != null && !childState.isModal()) { - nonModals.add(child); - } - - } - - - return nonModals; - - - } - - - /** - * Retrieves a list of non-modal application child nodes - it will only process the direct children of the - * application node, i.e. the frame, window, dialog nodes that can be modal. - * @param applicationNode The application node of the application to get non-modal windows for. - * @return A list of non-modal windows for an application. - */ - public static List getModalApplicationChildNodes(AtSpiAccessible applicationNode) { - - - if (applicationNode.role() != AtSpiRoles.Application) { - throw new IllegalArgumentException("The application node should be an AtSpiAccessible with role 'Application'."); - } - - - ArrayList modals = new ArrayList<>(); - - - // Check the children - this could be frames, windows or modal dialogs - add the non-modals to the list. - for (AtSpiAccessible child : applicationNode.children()) { - - AtSpiStateSet childState = child.states(); - - if (childState != null && childState.isModal()) { - modals.add(child); - } - - } - - - return modals; - - - } - - - /** - * Retrieves a list of application child nodes - it will only process the direct children of the - * application node, i.e. the frame, window, dialog nodes. - * @param applicationNode The application node of the application to get windows, frames, dialogs for. - * @return A list of windows, frames, dialogs for an application. - */ - public static List getApplicationWindowNodes(AtSpiAccessible applicationNode) { - - - if (applicationNode.role() != AtSpiRoles.Application) { - throw new IllegalArgumentException("The application node should be an AtSpiAccessible with role 'Application'."); - } - - - ArrayList windows = new ArrayList<>(); - - - // Check the children - this could be frames, windows or modal dialogs - add the windows, frames,dialogs - // to the list. This could be optimized by filtering unwanted stuff by role if there is any. - for (AtSpiAccessible child : applicationNode.children()) { - - AtSpiStateSet childState = child.states(); - - if (childState != null && !childState.isModal()) { - windows.add(child); - } - - } - - - return windows; - - - } - - - /** - * Determines the bounding box of the application on the screen. - * @param applicationNode The AtSpiAccessible application node of the application to get the bounding box for. - * @return The bounding box of the application or a bounding box with 0 values if the bounding box could not be determined. - */ - public static AtSpiRect getApplicationExtentsOnScreen(AtSpiAccessible applicationNode) { - - - if (applicationNode.role() != AtSpiRoles.Application) { - throw new IllegalArgumentException("The application node should be an AtSpiAccessible with role 'Application'."); - } - - - // Check the children - should be only one? Check all for the frame role and active state in any case to be sure. - for (AtSpiAccessible child : applicationNode.children()) { - if (child.role() == AtSpiRoles.Frame && child.component() != null) { - return child.component().extentsOnScreen(); - } - } - - - return new AtSpiRect(); - - } - - - /** - * Finds nodes with a certain role in the supplied node (which should have been processed by a method that - * creates parent - child relations. - * @param node The node to start from to search for a specific role. - * @param role The role the node should have. - * @return A list of AtSpiAccessible nodes with a certain role. - */ - public static List findNodesWithRole(AtSpiAccessible node, AtSpiRoles role) { - - - ArrayList nodesWithRole = new ArrayList<>(); - - - if (node.role() == role) { - nodesWithRole.add(node); - } - - - if (node.childCount() > 0) { - for (AtSpiAccessible a : node.children()) { - for (AtSpiAccessible ac : findNodesWithRole(a, role)) { - nodesWithRole.add(ac); - } - } - } - - - return nodesWithRole; - - } - - - /** - * - * @param name - * @param roles - * @param states - * @return - */ - public static List findNodes(String name, AtSpiRoles[] roles, AtSpiStateTypes[] states) { - - // TODO: implement finding a node with certain properties in a tree. - return null; - - } - - - /** - * Tries to find a focusable element of an AtSpiAccessible application child node. - * @param applicationNode Element to start from - which needs to be an AtSpiAccessible application node. - * @return An element that can be focused. - */ - public static AtSpiAccessible findFocusableApplicationElementNode(AtSpiAccessible applicationNode) { - - - if (applicationNode.role() != AtSpiRoles.Application) { - throw new IllegalArgumentException("The application node should be an AtSpiAccessible with role 'Application'."); - } - - return findFocusable(applicationNode); - - - } - - - /** - * Tries to find a focusable element. - * @param root Element to start from. - * @return An element that can be focused. - */ - private static AtSpiAccessible findFocusable(AtSpiAccessible root) { - - - if (root.states().isFocusable() && root.component() != null) { - return root; - } - - - for (AtSpiAccessible a : root.children()) { - - if (a.states().isFocusable() && a.component() != null) { - return a; - } - - if (a.children().size() > 0) { - - AtSpiAccessible ret = findFocusable(a); - - if (ret != null) { - return ret; - } - } - - } - - return null; - - } - - - /** - * Creates an AtSpiAccessible object with all of its descendants available to be able to be browsed as a tree. - * @param accessiblePtrStart Pointer to an AtSpiAccessible object where the tree will start. - * @param fillInfo Whether to create a tree with full info or just with parent - child relations. - * @return An AtSpiAccessible object with all of its descendants available. - */ - public static AtSpiAccessible createAccessibleTree(long accessiblePtrStart, boolean fillInfo) { - - - AtSpiAccessible parent = AtSpiAccessible.CreateInstance(accessiblePtrStart); - - createAccessibleTree(parent, fillInfo); - - return parent; - - - } - - - /** - * Creates an AtSpiAccessible object with all of its descendants available to be able to be browsed as a tree. - * @param root The AtSpiAccessible object that will act as root of the tree. - * @param fillInfo Whether to create a tree with full info or just with parent - child relations. - */ - public static void createAccessibleTree(AtSpiAccessible root, boolean fillInfo) { - if (root != null) { - root.createTree(fillInfo); - } - } - - - -} diff --git a/linux/src/org/testar/monkey/alayer/linux/atspi/enums/AtSpiCollectionSortOrders.java b/linux/src/org/testar/monkey/alayer/linux/atspi/enums/AtSpiCollectionSortOrders.java deleted file mode 100644 index 3b15fc7d5..000000000 --- a/linux/src/org/testar/monkey/alayer/linux/atspi/enums/AtSpiCollectionSortOrders.java +++ /dev/null @@ -1,50 +0,0 @@ -/*************************************************************************************************** -* -* Copyright (c) 2017 Open Universiteit - www.ou.nl -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, -* this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the copyright holder nor the names of its -* contributors may be used to endorse or promote products derived from -* this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -* POSSIBILITY OF SUCH DAMAGE. -*******************************************************************************************************/ - - -package org.testar.monkey.alayer.linux.atspi.enums; - - -/** - * Enumeration used by interface AtspiCollection to specify the way AtspiAccesible objects should be sorted. - */ -public enum AtSpiCollectionSortOrders { - - - Invalid, - Canonical, - Flow, - Tab, - ReverseCanonical, - ReverseFlow, - ReverseTab, - LastDefined - - -} diff --git a/linux/src/org/testar/monkey/alayer/linux/atspi/enums/AtSpiCollectionTreeTraversalTypes.java b/linux/src/org/testar/monkey/alayer/linux/atspi/enums/AtSpiCollectionTreeTraversalTypes.java deleted file mode 100644 index 601c87c76..000000000 --- a/linux/src/org/testar/monkey/alayer/linux/atspi/enums/AtSpiCollectionTreeTraversalTypes.java +++ /dev/null @@ -1,46 +0,0 @@ -/*************************************************************************************************** -* -* Copyright (c) 2017 Open Universiteit - www.ou.nl -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, -* this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the copyright holder nor the names of its -* contributors may be used to endorse or promote products derived from -* this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -* POSSIBILITY OF SUCH DAMAGE. -*******************************************************************************************************/ - - -package org.testar.monkey.alayer.linux.atspi.enums; - - -/** - * Enumeration used by interface AtspiCollection to specify restrictions on AtspiAccesible objects to be traversed. - */ -public enum AtSpiCollectionTreeTraversalTypes { - - - RestrictChildren, - RestrictSibling, - Inorder, - LastDefined - - -} diff --git a/linux/src/org/testar/monkey/alayer/linux/atspi/enums/AtSpiComponentLayers.java b/linux/src/org/testar/monkey/alayer/linux/atspi/enums/AtSpiComponentLayers.java deleted file mode 100644 index 9e310af85..000000000 --- a/linux/src/org/testar/monkey/alayer/linux/atspi/enums/AtSpiComponentLayers.java +++ /dev/null @@ -1,106 +0,0 @@ -/*************************************************************************************************** -* -* Copyright (c) 2017 Open Universiteit - www.ou.nl -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, -* this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the copyright holder nor the names of its -* contributors may be used to endorse or promote products derived from -* this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -* POSSIBILITY OF SUCH DAMAGE. -*******************************************************************************************************/ - - -package org.testar.monkey.alayer.linux.atspi.enums; - - -/** - * The AtspiComponentLayer of an AtspiComponent instance indicates its relative stacking order with respect - * to the onscreen visual representation of the UI. AtspiComponentLayer, in combination with AtspiComponent - * bounds information, can be used to compute the visibility of all or part of a component. This is important - * in programmatic determination of region-of-interest for magnification, and in flat screen review models of - * the screen, as well as for other uses. Objects residing in two of the AtspiComponentLayer categories support - * further z-ordering information, with respect to their peers in the same layer: namely, ATSPI_LAYER_WINDOW and - * ATSPI_LAYER_MDI . Relative stacking order for other objects within the same layer is not available; the - * recommended heuristic is first child paints first. In other words, assume that the first siblings in the - * child list are subject to being overpainted by later siblings if their bounds intersect. The order of - * layers, from bottom to top, is: ATSPI_LAYER_BACKGROUND , ATSPI_LAYER_WINDOW , ATSPI_LAYER_MDI , - * ATSPI_LAYER_CANVAS , ATSPI_LAYER_WIDGET , ATSPI_LAYER_POPUP , and ATSPI_LAYER_OVERLAY . - */ -public enum AtSpiComponentLayers { - - - /** - * Indicates an error condition or uninitialized value. - */ - Invalid, - - - /** - * The bottom-most layer, over which everything else is painted. The 'desktop background' - * is generally in this layer. - */ - Background, - - - /** - * The 'background' layer for most content renderers and UI AtspiComponent containers. - */ - Canvas, - - - /** - * The layer in which the majority of ordinary 'foreground' widgets reside. - */ - Widget, - - - /** - * A special layer between ATSPI_LAYER_CANVAS and ATSPI_LAYER_WIDGET , - * in which the 'pseudo windows' (e.g. the MDI frames) reside. See atspi_component_get_mdi_z_order. - */ - Mdi, - - - /** - * A layer for popup window content, above ATSPI_LAYER_WIDGET . - */ - Popup, - - - /** - * The topmost layer. - */ - Overlay, - - - /** - * The layer in which a toplevel window background usually resides. - */ - Window, - - - /** - * Used only to determine the end of the enumeration. - */ - LastDefined - - -} diff --git a/linux/src/org/testar/monkey/alayer/linux/atspi/enums/AtSpiCoordTypes.java b/linux/src/org/testar/monkey/alayer/linux/atspi/enums/AtSpiCoordTypes.java deleted file mode 100644 index 626804d04..000000000 --- a/linux/src/org/testar/monkey/alayer/linux/atspi/enums/AtSpiCoordTypes.java +++ /dev/null @@ -1,52 +0,0 @@ -/*************************************************************************************************** -* -* Copyright (c) 2017 Open Universiteit - www.ou.nl -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, -* this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the copyright holder nor the names of its -* contributors may be used to endorse or promote products derived from -* this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -* POSSIBILITY OF SUCH DAMAGE. -*******************************************************************************************************/ - - -package org.testar.monkey.alayer.linux.atspi.enums; - -/** - * Enumeration used by AtspiComponent, AtspiImage, and AtspiText interfaces to specify whether coordinates are - * relative to the window or the screen. - */ -public enum AtSpiCoordTypes { - - - /** - * Specifies xy coordinates relative to the screen. - */ - Screen, - - - /** - * Specifies xy coordinates relative to the widget's top-level window. - */ - Window - - -} diff --git a/linux/src/org/testar/monkey/alayer/linux/atspi/enums/AtSpiLocaleTypes.java b/linux/src/org/testar/monkey/alayer/linux/atspi/enums/AtSpiLocaleTypes.java deleted file mode 100644 index 189e58b77..000000000 --- a/linux/src/org/testar/monkey/alayer/linux/atspi/enums/AtSpiLocaleTypes.java +++ /dev/null @@ -1,77 +0,0 @@ -/*************************************************************************************************** -* -* Copyright (c) 2017 Open Universiteit - www.ou.nl -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, -* this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the copyright holder nor the names of its -* contributors may be used to endorse or promote products derived from -* this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -* POSSIBILITY OF SUCH DAMAGE. -*******************************************************************************************************/ - - -package org.testar.monkey.alayer.linux.atspi.enums; - - -/** - * Used by interfaces AtspiText and AtspiDocument, this enumeration corresponds to the POSIX 'setlocale' enum values. - */ -public enum AtSpiLocaleTypes { - - - /** - * For localizable natural-language messages. - */ - Messages, - - - /** - * For regular expression matching and string collation. - */ - Collate, - - - /** - * For regular expression matching, character classification, conversion, - * case-sensitive comparison, and wide character functions. - */ - CType, - - - /** - * For monetary formatting. - */ - Monetary, - - - /** - * For number formatting (such as the decimal point and the thousands separator). - */ - Numeric, - - - /** - * For time and date formatting. - */ - Time - - -} diff --git a/linux/src/org/testar/monkey/alayer/linux/atspi/enums/AtSpiMatchTypes.java b/linux/src/org/testar/monkey/alayer/linux/atspi/enums/AtSpiMatchTypes.java deleted file mode 100644 index 2898c8610..000000000 --- a/linux/src/org/testar/monkey/alayer/linux/atspi/enums/AtSpiMatchTypes.java +++ /dev/null @@ -1,77 +0,0 @@ -/*************************************************************************************************** -* -* Copyright (c) 2017 Open Universiteit - www.ou.nl -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, -* this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the copyright holder nor the names of its -* contributors may be used to endorse or promote products derived from -* this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -* POSSIBILITY OF SUCH DAMAGE. -*******************************************************************************************************/ - - -package org.testar.monkey.alayer.linux.atspi.enums; - - -/** - * Enumeration used by AtspiMatchRule to specify how to interpret AtspiAccessible objects. - */ -public enum AtSpiMatchTypes { - - - /** - * Indicates an error condition or uninitialized value. - */ - Invalid, - - - /** - * TRUE if all of the criteria are met. - */ - All, - - - /** - * TRUE if any of the criteria are met. - */ - Any, - - - /** - * TRUE if none of the criteria are met. - */ - None, - - - /** - * Same as ATSPI_Collection_MATCH_ALL if the criteria is non-empty; - * for empty criteria this rule requires returned value to also have empty set. - */ - Empty, - - - /** - * Used only to determine the end of the enumeration. - */ - LastDefined - - -} diff --git a/linux/src/org/testar/monkey/alayer/linux/atspi/enums/AtSpiRelations.java b/linux/src/org/testar/monkey/alayer/linux/atspi/enums/AtSpiRelations.java deleted file mode 100644 index 22f1dfd2d..000000000 --- a/linux/src/org/testar/monkey/alayer/linux/atspi/enums/AtSpiRelations.java +++ /dev/null @@ -1,182 +0,0 @@ -/*************************************************************************************************** -* -* Copyright (c) 2017 Open Universiteit - www.ou.nl -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, -* this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the copyright holder nor the names of its -* contributors may be used to endorse or promote products derived from -* this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -* POSSIBILITY OF SUCH DAMAGE. -*******************************************************************************************************/ - - -package org.testar.monkey.alayer.linux.atspi.enums; - - -/** - * AtspiRelationType specifies a relationship between objects (possibly one-to-many or many-to-one) outside of the - * normal parent/child hierarchical relationship. It allows better semantic identification of how objects are - * associated with one another. For instance the ATSPI_RELATION_LABELLED_BY relationship may be used to identify - * labelling information that should accompany the accessible name property when presenting an object's content or - * identity to the end user. Similarly, ATSPI_RELATION_CONTROLLER_FOR can be used to further specify the context in - * which a valuator is useful, and/or the other UI components which are directly effected by user interactions with - * the valuator. Common examples include association of scrollbars with the viewport or panel which they control. - * - * Enumeration used to specify the type of relation encapsulated in an AtspiRelation object - */ -public enum AtSpiRelations { - - - /** - * Not a meaningful relationship; clients should not normally encounter this AtspiRelationType value. - */ - Null, - - - /** - * Object is a label for one or more other objects. - */ - LabelFor, - - - /** - * Object is labelled by one or more other objects. - */ - LabelledBy, - - - /** - * Object is an interactive object which modifies the state, onscreen location, or other attributes - * of one or more target objects. - */ - ControllerFor, - - - /** - * Object state, position, etc. is modified/controlled by user interaction with one or more other objects. - * For instance a viewport or scroll pane may be ATSPI_RELATION_CONTROLLED_BY scrollbars. - */ - ControlledBy, - - - /** - * Object has a grouping relationship (e.g. 'same group as') to one or more other objects. - */ - MemberOf, - - - /** - * Object is a tooltip associated with another object. - */ - ToolTipFor, - - - /** - * Object is a child of the target. - */ - NodeChildOf, - - - /** - * Object is a parent of the target. - */ - NodeParentOf, - - - /** - * Used to indicate that a relationship exists, but its type is not specified in the enumeration. - */ - Extended, - - - /** - * Object renders content which flows logically to another object. For instance, text in a paragraph may flow to - * another object which is not the 'next sibling' in the accessibility hierarchy. - */ - FlowsTo, - - - /** - * Reciprocal of ATSPI_RELATION_FLOWS_TO. - */ - FlowsFrom, - - - /** - * Object is visually and semantically considered a subwindow of another object, even though it is not the - * object's child. Useful when dealing with embedded applications and other cases where the widget - * hierarchy does not map cleanly to the onscreen presentation. - */ - SubWindowOf, - - - /** - * Similar to ATSPI_RELATION_SUBWINDOW_OF, but specifically used for cross-process embedding. - */ - Embeds, - - - /** - * Reciprocal of ATSPI_RELATION_EMBEDS. Used to denote content rendered by embedded - * renderers that live in a separate process space from the embedding context. - */ - EmbeddedBy, - - - /** - * Denotes that the object is a transient window or frame associated with another onscreen object. Similar - * to ATSPI_TOOLTIP_FOR , but more general. Useful for windows which are technically toplevels but which, - * for one or more reasons, do not explicitly cause their associated window to lose 'window focus'. Creation - * of an ATSPI_ROLE_WINDOW object with the ATSPI_RELATION_POPUP_FOR relation usually requires some presentation - * action on the part of assistive technology clients, even though the previous toplevel ATSPI_ROLE_FRAME object - * may still be the active window. - */ - PopupFor, - - - /** - * This is the reciprocal relation to ATSPI_RELATION_POPUP_FOR . - */ - ParentWindowOf, - - - /** - * Indicates that an object provides descriptive information about another object; more verbose than - * ATSPI_RELATION_LABEL_FOR . - */ - DescriptionFor, - - - /** - * Indicates that another object provides descriptive information about this object; - * more verbose than ATSPI_RELATION_LABELLED_BY . - */ - DescribedBy, - - - /** - * Do not use as a parameter value, used to determine the size of the enumeration. - */ - LastDefined - - - -} diff --git a/linux/src/org/testar/monkey/alayer/linux/atspi/enums/AtSpiRoles.java b/linux/src/org/testar/monkey/alayer/linux/atspi/enums/AtSpiRoles.java deleted file mode 100644 index 30b9e90a3..000000000 --- a/linux/src/org/testar/monkey/alayer/linux/atspi/enums/AtSpiRoles.java +++ /dev/null @@ -1,173 +0,0 @@ -/*************************************************************************************************** -* -* Copyright (c) 2016, 2017 Open Universiteit - www.ou.nl -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, -* this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the copyright holder nor the names of its -* contributors may be used to endorse or promote products derived from -* this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -* POSSIBILITY OF SUCH DAMAGE. -*******************************************************************************************************/ - - -package org.testar.monkey.alayer.linux.atspi.enums; - - -/** - * Enumerates possible AT-SPI roles used to specify the UI role of an accessible object. - */ -public enum AtSpiRoles { - - - /** - * A role indicating an error condition, such as uninitialized Role data. - */ - Invalid, //A Role indicating an error condition, such as uninitialized Role data. - AcceleratorLabel, //Object is a label indicating the keyboard accelerators for the parent. - Alert, //Object is used to alert the user about something. - Animation, //Object contains a dynamic or moving image of some kind. - Arrow, //Object is a 2d directional indicator. - Calendar, //Object contains one or more dates, usually arranged into a 2d list. - Canvas, //Object that can be drawn into and is used to trap events. - CheckBox, //A choice that can be checked or unchecked and provides a separate indicator for the current state. - CheckMenuItem, //A menu item that behaves like a check box - ColorChooser, //A specialized dialog that lets the user choose a color. - ColumnHeader, //The header for a column of data. - ComboBox, //A list of choices the user can select from. - DateEditor, //An object which allows entry of a date. - DesktopIcon, //An inconifed internal frame within a DESKTOP_PANE. - DesktopFrame, //A pane that supports internal frames and iconified versions of those internal frames. - Dial, //An object that allows a value to be changed via rotating a visual element, or which displays a value via such a rotating element. - Dialog, //A top level window with title bar and a border. - DirectoryPane, //A pane that allows the user to navigate through and select the contents of a directory. - DrawingArea, //A specialized dialog that displays the files in the directory and lets the user select a file, browse a different directory, or specify a filename. - FileChooser, //An object used for drawing custom user interface elements. - Filler, //A object that fills up space in a user interface. - FocusTraversable, //reserved for future use. - FontChooser, //Allows selection of a display font. - Frame, //A top level window with a title bar, border, menubar, etc. - GlassPane, //A pane that is guaranteed to be painted on top of all panes beneath it. - HTMLContainer, //A document container for HTML, whose children represent the document content. - Icon, //A small fixed size picture, typically used to decorate components. - Image, //An image, typically static. - InternalFrame, //A frame-like object that is clipped by a desktop pane. - Label, //An object used to present an icon or short string in an interface. - LayeredPane, //A specialized pane that allows its children to be drawn in layers, providing a form of stacking order. - List, //An object that presents a list of objects to the user and allows the user to select one or more of them. - ListItem, //An object that represents an element of a list. - Menu, //An object usually found inside a menu bar that contains a list of actions the user can choose from. - MenuBar, //An object usually drawn at the top of the primary dialog box of an application that contains a list of menus the user can choose from. - MenuItem, //An object usually contained in a menu that presents an action the user can choose. - OptionPane, //A specialized pane whose primary use is inside a DIALOG. - PageTab, //An object that is a child of a page tab list. - PageTabList, //An object that presents a series of panels (or page tabs), one at a time, through some mechanism provided by the object. - Panel, //A generic container that is often used to group objects. - PasswordText, //A text object uses for passwords, or other places where the text content is not shown visibly to the user. - PopupMenu, //A temporary window that is usually used to offer the user a list of choices, and then hides when the user selects one of those choices. - ProgressBar, //An object used to indicate how much of a task has been completed. - PushButton, //An object the user can manipulate to tell the application to do something. - RadioButton, //A specialized check box that will cause other radio buttons in the same group to become uncghecked when this one is checked. - RadioMenuItem, //Object is both a menu item and a "radio button" - RootPane, //A specialized pane that has a glass pane and a layered pane as its children. - RowHeader, //The header for a row of data. - ScrollBar, //An object usually used to allow a user to incrementally view a large amount of data by moving the bounds of a viewport along a one-dimensional axis. - ScrollPane, //An object that allows a user to incrementally view a large amount of information. - Separator, //An object usually contained in a menu to provide a visible and logical separation of the contents in a menu. - Slider, //An object that allows the user to select from a bounded range. - SpinButton, //An object which allows one of a set of choices to be selected, and which displays the current choice. - SplitPane, //A specialized panel that presents two other panels at the same time. - StatusBar, //Object displays non-quantitative status information - Table, //An object used to repesent information in terms of rows and columns. - TableCell, //A 'cell' or discrete child within a Table. - TableColumnHeader, //An object which labels a particular column in a Table. - TableRowHeader, //An object which labels a particular row in a Table. - TearoffMenuItem, //Object allows menu to be removed from menubar and shown in its own window. - Terminal, //An object that emulates a terminal. - Text, //An object that presents text to the user, of nonspecific type. - ToggleButton, //A specialized push button that can be checked or unchecked, but does not procide a separate indicator for the current state. - ToolBar, //A bar or palette usually composed of push buttons or toggle buttons. - ToolTip, //An object that provides information about another object. - Tree, //An object used to repsent hierarchical information to the user. - TreeTable, //An object that presents both tabular and hierarchical info to the user. - Unknown, //The object contains some Accessible information, but its role is not known. - Viewport, //An object usually used in a scroll pane, or to otherwise clip a larger object or content renderer to a specific onscreen viewport. - Window, //A ¨top level window¨ with no title or border. - Extended, //means that the role for this item is known, but not included in the core enumeration - Header, //An object that serves as a document header. - Footer, //An object that serves as a document footer. - Paragraph, //An object which is contains a single paragraph of text content. - Ruler, //An object which describes margins and tab stops, etc. - Application, //An object corresponding to the toplevel accessible of an application, which may contain ROLE_FRAME objects or other accessible objects. - Autocomplete, //The object is a dialog or list containing items for insertion into an entry widget, for instance a list of words for completion of a text entry. - EditBar, //The object is an editable text object in a toolbar. - Embedded, //The object is an embedded component container. - Entry, //The object is a component whose textual content may be entered or modified by the user, provided STATE_EDITABLE is present. - Chart, //The object is a graphical depiction of quantitative data. - Caption, //The object contains descriptive information, usually textual, about another user interface element such as a table, chart, or image. - DocumentFrame, //The object is a visual frame or container which contains a view of document content. - Heading, //The object serves as a heading for content which follows it in a document. - Page, //The object is a containing instance which encapsulates a page of information. - Section, //The object is a containing instance of document content which constitutes a particular 'logical' section of the document. - RedundantObject, //The object is redundant with another object in the hierarchy, and is exposed for purely technical reasons. Objects of this role should be ignored by clients, if they are encountered at all. - Form, //The object is a containing instance of document content which has within it components with which the user can interact in order to input information; i.e. the object is a container for pushbuttons, comboboxes, text input fields, and other 'GUI' components. ATSPI_ROLE_FORM should not, in general, be used for toplevel GUI containers or dialogs, but should be reserved for 'GUI' containers which occur within document content, for instance within Web documents, presentations, or text documents. Unlike other GUI containers and dialogs which occur inside application instances, ATSPI_ROLE_FORM containers' components are associated with the current document, rather than the current foreground application or viewer instance. - Link, //The object is a hypertext anchor, i.e. a "link" in a hypertext document. Such objects are distinct from 'inline' content which may also use the AtspiHypertext/AtspiHyperlink interfacesto indicate the range/location within a text object where an inline or embedded object lies. - InputMethodWindow, //The object is a window or similar viewport which is used to allow composition or input of a 'complex character', in other words it is an "input method window". - TableRow, //A row in a table. - TreeItem, //An object that represents an element of a tree. - DocumentSpreadsheet, //A document frame which contains a spreadsheet. - DocumentPresentation, //A document frame which contains a presentation or slide - DocumentText, //A document frame which contains textual content, such as found in a word processing application. - DocumentWeb, //A document frame which contains HTML or other markup suitable for display in a web browser. - DocumentEmail, //A document frame which contains email content to be displayed or composed either in plain text or HTML. - Comment, //An object found within a document and designed to present a comment, note, or other annotation. In some cases, this object might not be visible until activated. - ListBox, //A non-collapsible list of choices the user can select from. - Grouping, //A group of related widgets. This group typically has a label. - ImageMap, //An image map object. Usually a graphic with multiple hotspots, where each hotspot can be activated resulting in the loading of another document or section of a document. - Notification, //A transitory object designed to present a message to the user, typically at the desktop level rather than inside a particular application. - InfoBar, //An object designed to present a message to the user within an existing window. - LevelBar, //A bar that serves as a level indicator to, for instance, show the strength of a password or the state of a battery. Since: 2.8 - TitleBar, //A bar that serves as the title of a window or a dialog. Since : 2.12 - BlockQuote, //An object which contains a text section that is quoted from another source. Since : 2.12 - Audio, //An object which represents an audio element. Since : 2.1 - Video, //An object which represents an video element. Since : 2.1 - Definition, //A definition of a term or concept. Since : 2.12 - Article, //A section of a page that consists of a composition that forms an independent part of a document, page, or site. Examples: A blog entry, a news story, a forum post. Since : 2.12 - Landmark, //A region of a web page intended as a navigational landmark. This is designed to allow Assistive Technologies to provide quick navigation among key regions within a document. Since : 2.12 - Log, //A text widget or container holding log content, such as chat history and error logs. In this role there is a relationship between the arrival of new items in the log and the reading order. The log contains a meaningful sequence and new information is added only to the end of the log, not at arbitrary points. Since : 2.12 - Marquee, //A container where non-essential information changes frequently. Common usages of marquee include stock tickers and ad banners. The primary difference between a marquee and a log is that logs usually have a meaningful order or sequence of important content changes. Since : 2.12 - Math, //A text widget or container that holds a mathematical expression. Since : 2.12 - Rating, //A widget whose purpose is to display a rating, such as the number of stars associated with a song in a media player. Objects of this role should also implement AtspiValue. Since : 2.12 - Timer, //An object containing a numerical counter which indicates an amount of elapsed time from a start point, or the time remaining until an end point. Since : 2.12 - Static, //A generic non-container object whose purpose is to display a brief amount of information to the user and whose role is known by the implementor but lacks semantic value for the user. Examples in which ATSPI_ROLE_STATIC is appropriate include the message displayed in a message box and an image used as an alternative means to display text. ATSPI_ROLE_STATIC should not be applied to widgets which are traditionally interactive, objects which display a significant amount of content, or any object which has an accessible relation pointing to another object. The displayed information, as a general rule, should be exposed through the accessible name of the object. For labels which describe another widget, see ATSPI_ROLE_LABEL . For text views, see ATSPI_ROLE_TEXT . For generic containers, see ATSPI_ROLE_PANEL . For objects whose role is not known by the implementor, see ATSPI_ROLE_UNKNOWN . Since : 2.16. - MathFraction, //An object that represents a mathematical fraction. - MathRoot, //An object that represents a mathematical expression displayed with a radical. Since : 2.16. - Subscript, //An object that contains text that is displayed as a subscript. Since : 2.16. - Superscript, //An object that contains text that is displayed as a superscript. Since : 2.16. - LastDefined, //Not a valid role, used for finding end of enumeration. - - - - - - - - -} diff --git a/linux/src/org/testar/monkey/alayer/linux/atspi/enums/AtSpiStateTypes.java b/linux/src/org/testar/monkey/alayer/linux/atspi/enums/AtSpiStateTypes.java deleted file mode 100644 index 4de754c8b..000000000 --- a/linux/src/org/testar/monkey/alayer/linux/atspi/enums/AtSpiStateTypes.java +++ /dev/null @@ -1,368 +0,0 @@ -/*************************************************************************************************** -* -* Copyright (c) 2017 Open Universiteit - www.ou.nl -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, -* this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the copyright holder nor the names of its -* contributors may be used to endorse or promote products derived from -* this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -* POSSIBILITY OF SUCH DAMAGE. -*******************************************************************************************************/ - - -package org.testar.monkey.alayer.linux.atspi.enums; - -/** - * Enumeration used by various interfaces indicating every possible state an AtspiAccesible object can assume. - */ -public enum AtSpiStateTypes { - - - /** - * Indicates an invalid state - probably an error condition. - */ - Invalid, - - - /** - * Indicates a window is currently the active window, or an object is the active subelement within a container or - * table. ATSPI_STATE_ACTIVE should not be used for objects which have ATSPI_STATE_FOCUSABLE or ATSPI_STATE_SELECTABLE: - * Those objects should use ATSPI_STATE_FOCUSED and ATSPI_STATE_SELECTED respectively. ATSPI_STATE_ACTIVE is a means to - * indicate that an object which is not focusable and not selectable is the currently-active item within its parent container. - */ - Active, - - - /** - * Indicates that the object is armed. - */ - Armed, - - - /** - * Indicates the current object is busy, i.e. onscreen representation is in the process of changing, - * or the object is temporarily unavailable for interaction due to activity already in progress. - */ - Busy, - - - /** - * Indicates this object is currently checked. - */ - Checked, - - - /** - * Indicates this object is collapsed. - */ - Collapsed, - - - /** - * Indicates that this object no longer has a valid backing widget (for instance, if its peer object has been destroyed). - */ - Defunct, - - - /** - * Indicates the user can change the contents of this object. - */ - Editable, - - - /** - * Indicates that this object is enabled, i.e. that it currently reflects some application state. Objects that are - * "greyed out" may lack this state, and may lack the ATSPI_STATE_SENSITIVE if direct user interaction cannot - * cause them to acquire ATSPI_STATE_ENABLED . See ATSPI_STATE_SENSITIVE . - */ - Enabled, - - - /** - * Indicates this object allows progressive disclosure of its children. - */ - Expandable, - - - /** - * Indicates this object is expanded. - */ - Expanded, - - - /** - * Indicates this object can accept keyboard focus, which means all events resulting from typing on the keyboard - * will normally be passed to it when it has focus. - */ - Focusable, - - - /** - * Indicates this object currently has the keyboard focus. - */ - Focused, - - - /** - * Indicates that the object has an associated tooltip. - */ - HasTooltip, - - - /** - * Indicates the orientation of this object is horizontal. - */ - Horizontal, - - - /** - * Indicates this object is minimized and is represented only by an icon. - */ - Iconified, - - - /** - * Indicates something must be done with this object before the user can interact with an object in a different window. - */ - Modal, - - - /** - * Indicates this (text) object can contain multiple lines of text. - */ - MultiLine, - - - /** - * Indicates this object allows more than one of its children to be selected at the same time, or in the case of - * text objects, that the object supports non-contiguous text selections. - */ - MultiSelectable, - - - /** - * Indicates this object paints every pixel within its rectangular region. It also indicates an alpha value of unity, - * if it supports alpha blending. - */ - Opaque, - - - /** - * Indicates this object is currently pressed. - */ - Pressed, - - - /** - * Indicates the size of this object's size is not fixed. - */ - Resizable, - - - /** - * Indicates this object is the child of an object that allows its children to be selected and that this - * child is one of those children that can be selected. - */ - Selectable, - - - /** - * Indicates this object is the child of an object that allows its children to - * be selected and that this child is one of those children that has been selected. - */ - Selected, - - - /** - * Indicates this object is sensitive, e.g. to user interaction. ATSPI_STATE_SENSITIVE usually accompanies. - * ATSPI_STATE_ENABLED for user-actionable controls, but may be found in the absence of ATSPI_STATE_ENABLED - * if the current visible state of the control is "disconnected" from the application state. In such cases, - * direct user interaction can often result in the object gaining ATSPI_STATE_SENSITIVE , for instance if a user - * makes an explicit selection using an object whose current state is ambiguous or undefined. - * See ATSPI_STATE_ENABLED , ATSPI_STATE_INDETERMINATE . - */ - Sensitive, - - - /** - * Indicates this object, the object's parent, the object's parent's parent, and so on, are all 'shown' to the - * end-user, i.e. subject to "exposure" if blocking or obscuring objects do not interpose between this object - * and the top of the window stack. - */ - Showing, - - - /** - * Indicates this (text) object can contain only a single line of text. - */ - SingleLine, - - - /** - * Indicates that the information returned for this object may no longer be synchronized with the application - * state. This can occur if the object has ATSPI_STATE_TRANSIENT , and can also occur towards - * the end of the object peer's lifecycle. - */ - Stale, - - - /** - * Indicates this object is transient. - */ - Transient, - - - /** - * Indicates the orientation of this object is vertical; for example this state may appear on such objects - * as scrollbars, text objects (with vertical text flow), separators, etc. - */ - Vertical, - - - /** - * Indicates this object is visible, e.g. has been explicitly marked for exposure to the user. - * ATSPI_STATE_VISIBLE is no guarantee that the object is actually unobscured on the screen, only - * that it is 'potentially' visible, barring obstruction, being scrolled or clipped out of the field of view, - * or having an ancestor container that has not yet made visible. A widget is potentially onscreen if it has both - * ATSPI_STATE_VISIBLE and ATSPI_STATE_SHOWING . The absence of ATSPI_STATE_VISIBLE and ATSPI_STATE_SHOWING is - * semantically equivalent to saying that an object is 'hidden'. - */ - Visible, - - - /** - * Indicates that "active-descendant-changed" event is sent when children become 'active' (i.e. are selected - * or navigated to onscreen). Used to prevent need to enumerate all children in very large containers, - * like tables. The presence of ATSPI_STATE_MANAGES_DESCENDANTS is an indication to the client that the - * children should not, and need not, be enumerated by the client. Objects implementing this state are expected - * to provide relevant state notifications to listening clients, for instance notifications of visibility changes - * and activation of their contained child objects, without the client having previously requested references - * to those children. - */ - ManagesDescendants, - - - /** - * Indicates that a check box or other boolean indicator is in a state other than checked or not checked. - * This usually means that the boolean value reflected or controlled by the object does not apply consistently - * to the entire current context. For example, a checkbox for the "Bold" attribute of text may have - * ATSPI_STATE_INDETERMINATE if the currently selected text contains a mixture of weight attributes. - * In many cases interacting with a ATSPI_STATE_INDETERMINATE object will cause the context's corresponding - * boolean attribute to be homogenized, whereupon the object will lose ATSPI_STATE_INDETERMINATE and a - * corresponding state-changed event will be fired. - */ - Indeterminate, - - - /** - * Indicates that user interaction with this object is 'required' from the user, for instance before - * completing the processing of a form. - */ - Required, - - - /** - * Indicates that an object's onscreen content is truncated, e.g. a text value in a spreadsheet cell. - */ - Truncated, - - - /** - * Indicates this object's visual representation is dynamic, not static. This state may be applied to an object - * during an animated 'effect' and be removed from the object once its visual representation becomes static. - * Some applications, notably content viewers, may not be able to detect all kinds of animated content. - * Therefore the absence of this state should not be taken as definitive evidence that the object's visual - * representation is static; this state is advisory. - */ - Animated, - - - /** - * This object has indicated an error condition due to failure of input validation. For instance, - * a form control may acquire this state in response to invalid or malformed user input. - */ - InvalidEntry, - - - /** - * This state indicates that the object in question implements some form of typeahead or pre-selection behavior - * whereby entering the first character of one or more sub-elements causes those elements to scroll into view - * or become selected. Subsequent character input may narrow the selection further as long as one or more - * sub-elements match the string. This state is normally only useful and encountered on objects that - * implement AtspiSelection. In some cases the typeahead behavior may result in full or partial completion - * of the data in the input field, in which case these input events may trigger text-changed events from the source. - */ - SupportsAutoCompletion, - - - /** - * This state indicates that the object in question supports text selection. It should only be - * exposed on objects which implement the AtspiText interface, in order to distinguish - * this state from ATSPI_STATE_SELECTABLE , which infers that the object in question is - * a selectable child of an object which implements AtspiSelection. While similar, - * text selection and subelement selection are distinct operations. - */ - SelectableText, - - - /** - * This state indicates that the object in question is the 'default' interaction object in a dialog, - * i.e. the one that gets activated if the user presses "Enter" when the dialog is initially posted. - */ - IsDefault, - - - /** - * This state indicates that the object (typically a hyperlink) has already been activated or - * invoked, with the result that some backing data has been downloaded or rendered. - */ - Visited, - - - /** - * Indicates this object has the potential to be checked, such as a checkbox or toggle-able table cell. Since : 2.12 - */ - Checkable, - - - /** - * Indicates that the object has a popup context menu or sub-level menu which may or may not be showing. - * This means that activation renders conditional content. Note that ordinary tooltips are not - * considered popups in this context. Since : 2.12 - */ - HasPopup, - - - /** - * Indicates that an object which is ENABLED and SENSITIVE has a value which can be read, - * but not modified, by the user. Since : 2.16 - */ - ReadOnly, - - - /** - * This value of the enumeration should not be used as a parameter, - * it indicates the number of items in the AtspiStateType enumeration - */ - LastDefined - - -} diff --git a/linux/src/org/testar/monkey/alayer/linux/enums/AtSpiElementOrientations.java b/linux/src/org/testar/monkey/alayer/linux/enums/AtSpiElementOrientations.java deleted file mode 100644 index 4fa6cdadf..000000000 --- a/linux/src/org/testar/monkey/alayer/linux/enums/AtSpiElementOrientations.java +++ /dev/null @@ -1,64 +0,0 @@ -/*************************************************************************************************** -* -* Copyright (c) 2017 Open Universiteit - www.ou.nl -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, -* this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the copyright holder nor the names of its -* contributors may be used to endorse or promote products derived from -* this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -* POSSIBILITY OF SUCH DAMAGE. -*******************************************************************************************************/ - - -package org.testar.monkey.alayer.linux.enums; - - -/** - * Defines orientations an AtSpiElement can be in. - */ -public enum AtSpiElementOrientations { - - - /** - * The orientation is undefined or unknown. - */ - Undefined, - - - /** - * The orientation of the element is horizontal. - */ - Horizontal, - - - /** - * The orientation of the element is vertical. - */ - Vertical, - - - /** - * The orientation of the element is both horizontal and vertical (if that's even possible). - */ - HorizontalAndVertical - - -} diff --git a/linux/src/org/testar/monkey/alayer/linux/gdiplus/LibGdiPlus.java b/linux/src/org/testar/monkey/alayer/linux/gdiplus/LibGdiPlus.java deleted file mode 100644 index 5303a202b..000000000 --- a/linux/src/org/testar/monkey/alayer/linux/gdiplus/LibGdiPlus.java +++ /dev/null @@ -1,82 +0,0 @@ -/*************************************************************************************************** -* -* Copyright (c) 2017 Open Universiteit - www.ou.nl -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, -* this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the copyright holder nor the names of its -* contributors may be used to endorse or promote products derived from -* this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -* POSSIBILITY OF SUCH DAMAGE. -*******************************************************************************************************/ - - -package org.testar.monkey.alayer.linux.gdiplus; - - -import org.bridj.BridJ; -import org.bridj.Pointer; -import org.bridj.ann.Library; - -import java.io.IOException; - - -/** - * Represents a canvas for a linux screen on which can be painted. - */ -@Library("libgdiplus") -public class LibGdiPlus { - - - static{ - try { - BridJ.getNativeLibrary("libgdiplus"); - } catch (IOException e) { - e.printStackTrace(); - } - BridJ.register(); - } - - -// /** -// * The MonitorFromPoint function retrieves a handle to the display monitor that contains a specified point. -// * @param pt A POINT structure that specifies the point of interest in virtual-screen coordinates. -// * @param dwFlags Determines the function's return value if the point is not contained within any display monitor. -// * @return If the point is contained by a display monitor, the return value is an HMONITOR handle to that -// * display monitor. If the point is not contained by a display monitor, the return value depends -// * on the value of dwFlags. -// */ -// public static native long MonitorFromPoint(Point pt, long dwFlags); -// -// -// /** -// * The CreateCompatibleDC function creates a memory device context (DC) compatible with the specified device. -// * @param hdc A handle to an existing DC. If this handle is NULL, the function creates a memory DC compatible -// * with the application's current screen. -// * @return If the function succeeds, the return value is the handle to a memory DC. -// * If the function fails, the return value is NULL. -// */ -// public static native long CreateCompatibleDC(long hdc); - - - public static native long GdiplusStartup(Pointer token, Pointer input, Pointer output); - - -} diff --git a/linux/src/org/testar/monkey/alayer/linux/glib/GArray.java b/linux/src/org/testar/monkey/alayer/linux/glib/GArray.java deleted file mode 100644 index e418f8d9e..000000000 --- a/linux/src/org/testar/monkey/alayer/linux/glib/GArray.java +++ /dev/null @@ -1,229 +0,0 @@ -/*************************************************************************************************** -* -* Copyright (c) 2017 Open Universiteit - www.ou.nl -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, -* this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the copyright holder nor the names of its -* contributors may be used to endorse or promote products derived from -* this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -* POSSIBILITY OF SUCH DAMAGE. -*******************************************************************************************************/ - - -package org.testar.monkey.alayer.linux.glib; - -import org.bridj.Pointer; -import org.testar.monkey.alayer.linux.atspi.LibAtSpi; - -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; - - -/** - * Java implementation of the GArray object. - */ -public class GArray { - - - //region Properties - - - private Class _elementType; - - - protected long _arrayPtr; - public long arrayPtr() { - return _arrayPtr; - } - - - /** - * Gets the pointer to where the actual data is stored. - * @return The pointer to where the actual data is stored. - */ - public long dataPtr() { - - Pointer ptr = Pointer.pointerToAddress(_arrayPtr, long[].class, null); - - // The GArray structure starts with a long value to point to the data followed by an int to - // specify the length - so start at index 0. - return ptr.getLongAtIndex(0); - - } - - - /** - * Gets the length of the array. - * @return The length of the array. - */ - public int length() { - - - Pointer ptr = Pointer.pointerToAddress(_arrayPtr, int[].class, null); - - // The GArray structure starts with a long value to point to the data followed by an int to - // specify the length - a long is the size of two ints so start at index 2. - return ptr.getIntAtIndex(2); - - - } - - - /** - * Gets the size of the elements in the array in Bytes. - * @return The size of the elements in the array in Bytes. - */ - public int elementSize() { - return LibAtSpi.g_array_get_element_size(_arrayPtr); - } - - - protected List _elements; - public List elements() { - - - if (Objects.equals(_elementType.getName(), Long.class.getName())) { - - //noinspection unchecked - _elements = (List) new ArrayList(); - - Pointer ptr = Pointer.pointerToAddress(dataPtr(), long[].class, null); - - - // Retrieve each long value in the array. - for (int i = 0; i < length(); i++) { - ((ArrayList)_elements).add(ptr.getLongAtIndex(i)); - } - - - } else if (Objects.equals(_elementType.getName(), Integer.class.getName())) { - - //noinspection unchecked - _elements = (List) new ArrayList(); - - Pointer ptr = Pointer.pointerToAddress(dataPtr(), int[].class, null); - - - // Retrieve each long value in the array. - for (int i = 0; i < length(); i++) { - ((ArrayList)_elements).add(ptr.getIntAtIndex(i)); - } - - } else if (Objects.equals(_elementType.getName(), String.class.getName())) { - - - //noinspection unchecked - _elements = (List) new ArrayList(); - - - // Create a Pointer to point to the data in the array. - Pointer data = Pointer.pointerToAddress(dataPtr(), long[].class, null); - - // Retrieve each string ptr value in the array. - for (int i = 0; i < length(); i++) { - - // Get the string pointer element at index 'i' in the array and convert it to a Pointer to a string. - Pointer ptr = Pointer.pointerToAddress(data.getLongAtIndex(i), Byte.class, null); - - - // Retrieve the string value and add it to the elements list. - ((ArrayList)_elements).add(ptr.getCString()); - - } - - } - - - return _elements; - - //return _elements; - - } - - - //endregion - - - //region Constructors - - - /** - * Default empty constructor. - */ - private GArray() { - - } - - - /** - * Creates a new typed instance of a GArray. - * @param arrayPtr Pointer to a GArray structure. - * @param elementType The type of the GArray elements. - * @param The type of the GArray elements. - * @return An instance of a GArray object. - */ - public static GArray CreateInstance(long arrayPtr, Class elementType) { - - - if (arrayPtr == 0) { - return null; - } - - - // Create a new instance. - GArray aObj = new GArray(); - - - // Fill the instance's properties. - aObj._arrayPtr = arrayPtr; - aObj._elementType = elementType; - aObj._elements = aObj.elements(); - - - return aObj; - - - - - } - - - //endregion - - - //region Object overrides - - - /** - * Returns a string representation of a GArray object. - * @return Returns a string representation of a GArray object. - */ - @Override - public String toString() { - return "Size: " + length(); - } - - - //endregion - - -} diff --git a/linux/src/org/testar/monkey/alayer/linux/glib/GHashTable.java b/linux/src/org/testar/monkey/alayer/linux/glib/GHashTable.java deleted file mode 100644 index 4ea019874..000000000 --- a/linux/src/org/testar/monkey/alayer/linux/glib/GHashTable.java +++ /dev/null @@ -1,132 +0,0 @@ -/*************************************************************************************************** -* -* Copyright (c) 2017 Open Universiteit - www.ou.nl -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, -* this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the copyright holder nor the names of its -* contributors may be used to endorse or promote products derived from -* this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -* POSSIBILITY OF SUCH DAMAGE. -*******************************************************************************************************/ - - -package org.testar.monkey.alayer.linux.glib; - -import org.testar.monkey.alayer.linux.atspi.LibAtSpi; - - -/** - * Java implementation of the GHashTable object. - * - * !!! Not fully implemented - it does not retrieve any values, only the size. - */ -public class GHashTable { - - - //region Properties - - - private long _hastTablePtr; - public long hashTablePtr() { - return _hastTablePtr; - } - - - public int size() { - return LibAtSpi.g_hash_table_size(_hastTablePtr); - } - - - //endregion - - - //region Constructors - - - /** - * Default empty constructor. - */ - private GHashTable() { - - } - - - /** - * Creates a new instance of an GHashTable object from a pointer. - * @param hashTablePtr Pointer to the GHashTable object. - * @return A Java instance of an GHashTable object. - */ - public static GHashTable CreateInstance(long hashTablePtr) { - - - if (hashTablePtr == 0) { - return null; - } - - - // Create a new instance. - GHashTable htObj = new GHashTable(); - - - // Fill the instance's properties. - fillInstance(hashTablePtr, htObj); - - - return htObj; - - } - - - /** - * Fills an GHashTable object's information. - * @param hashTablePtr Pointer to the GHashTable object. - * @param htObj The Java instance of an GHashTable object. - */ - private static void fillInstance(long hashTablePtr, GHashTable htObj) { - - - // Fill the properties with the information. - htObj._hastTablePtr = hashTablePtr; - - - } - - - //endregion - - - //region Object overrides - - - /** - * Returns a string representation of an GHashTable object. - * @return Returns a string representation of an GHashTable object. - */ - @Override - public String toString() { - return "Size: " + size(); - } - - - //endregion - - -} diff --git a/linux/src/org/testar/monkey/alayer/linux/glib/GLibHelper.java b/linux/src/org/testar/monkey/alayer/linux/glib/GLibHelper.java deleted file mode 100644 index 822bcd02b..000000000 --- a/linux/src/org/testar/monkey/alayer/linux/glib/GLibHelper.java +++ /dev/null @@ -1,117 +0,0 @@ -/*************************************************************************************************** -* -* Copyright (c) 2017 Open Universiteit - www.ou.nl -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, -* this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the copyright holder nor the names of its -* contributors may be used to endorse or promote products derived from -* this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -* POSSIBILITY OF SUCH DAMAGE. -*******************************************************************************************************/ - - -package org.testar.monkey.alayer.linux.glib; - -import org.bridj.Pointer; - -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; - -/** - * Class to help with glib operations. - */ -public class GLibHelper { - - - /** - * Creates a list of elements of a certain type by reading memory in a certain location. - * @param dataPtr Pointer to the memory the data is stored. - * @param dataStructureLength The length of the structure in which the elements are stored. - * @param elementType The class type of the elements. - * @param The type of the elements. - * @return A list of typed elements read from memory. - */ - public static List createTypedList(long dataPtr, int dataStructureLength, Class elementType) { - - - List elements = null; - - - if (Objects.equals(elementType.getName(), Long.class.getName())) { - - //noinspection unchecked - elements = (List) new ArrayList(); - - Pointer ptr = Pointer.pointerToAddress(dataPtr, long[].class, null); - - - // Retrieve each long value in the list. - for (int i = 0; i < dataStructureLength; i++) { - ((ArrayList)elements).add(ptr.getLongAtIndex(i)); - } - - - } else if (Objects.equals(elementType.getName(), Integer.class.getName())) { - - //noinspection unchecked - elements = (List) new ArrayList(); - - Pointer ptr = Pointer.pointerToAddress(dataPtr, int[].class, null); - - - // Retrieve each long value in the list. - for (int i = 0; i < dataStructureLength; i++) { - ((ArrayList)elements).add(ptr.getIntAtIndex(i)); - } - - } else if (Objects.equals(elementType.getName(), String.class.getName())) { - - - //noinspection unchecked - elements = (List) new ArrayList(); - - - // Create a Pointer to point to the data in the list. - Pointer data = Pointer.pointerToAddress(dataPtr, long[].class, null); - - // Retrieve each string ptr value in the list. - for (int i = 0; i < dataStructureLength; i++) { - - // Get the string pointer element at index 'i' in the array and convert it to a Pointer to a string. - Pointer ptr = Pointer.pointerToAddress(data.getLongAtIndex(i), Byte.class, null); - - - // Retrieve the string value and add it to the elements list. - ((ArrayList)elements).add(ptr.getCString()); - - } - - } - - - return elements; - - - } - - -} diff --git a/linux/src/org/testar/monkey/alayer/linux/glib/GList.java b/linux/src/org/testar/monkey/alayer/linux/glib/GList.java deleted file mode 100644 index c46646f2c..000000000 --- a/linux/src/org/testar/monkey/alayer/linux/glib/GList.java +++ /dev/null @@ -1,154 +0,0 @@ -/*************************************************************************************************** -* -* Copyright (c) 2017 Open Universiteit - www.ou.nl -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, -* this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the copyright holder nor the names of its -* contributors may be used to endorse or promote products derived from -* this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -* POSSIBILITY OF SUCH DAMAGE. -*******************************************************************************************************/ - - -package org.testar.monkey.alayer.linux.glib; - - -import org.bridj.Pointer; -import org.testar.monkey.alayer.linux.atspi.LibAtSpi; - -import java.util.List; - - -/** - * Java implementation of the GList object. - */ -public class GList { - - - //region Properties - - - private Class _elementType; - - - protected long _listPtr; - public long listPtr() { - return _listPtr; - } - - - /** - * Gets the pointer to where the actual data is stored. - * @return The pointer to where the actual data is stored. - */ - public long dataPtr() { - - Pointer ptr = Pointer.pointerToAddress(_listPtr, long[].class, null); - - // The GList structure starts with a void* value to point to the data followed two pointers to - // next and previous - so start at index 0. - return ptr.getLongAtIndex(0); - - } - - - /** - * Gets the length of the array. - * @return The length of the array. - */ - public int length() { - return LibAtSpi.g_list_length(_listPtr); - } - - - protected List _elements; - public List elements() { - return GLibHelper.createTypedList(dataPtr(), length(), _elementType); - } - - - //endregion - - - //region Constructors - - - /** - * Default empty constructor. - */ - private GList() { - - } - - - /** - * Creates a new typed instance of a GList. - * @param listPtr Pointer to a GList structure. - * @param elementType The type of the GList elements. - * @param The type of the GList elements. - * @return An instance of a GList object. - */ - public static GList CreateInstance(long listPtr, Class elementType) { - - - if (listPtr == 0) { - return null; - } - - - // Create a new instance. - GList aObj = new GList(); - - - // Fill the instance's properties. - aObj._listPtr = listPtr; - aObj._elementType = elementType; - aObj._elements = aObj.elements(); - - - return aObj; - - - - - } - - - //endregion - - - //region Object overrides - - - /** - * Returns a string representation of a GList object. - * @return Returns a string representation of a GList object. - */ - @Override - public String toString() { - return "Size: " + length(); - } - - - //endregion - - -} diff --git a/linux/src/org/testar/monkey/alayer/linux/gtk3/LibGtk3.java b/linux/src/org/testar/monkey/alayer/linux/gtk3/LibGtk3.java deleted file mode 100644 index 16762407b..000000000 --- a/linux/src/org/testar/monkey/alayer/linux/gtk3/LibGtk3.java +++ /dev/null @@ -1,232 +0,0 @@ -/*************************************************************************************************** -* -* Copyright (c) 2017 Open Universiteit - www.ou.nl -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, -* this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the copyright holder nor the names of its -* contributors may be used to endorse or promote products derived from -* this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -* POSSIBILITY OF SUCH DAMAGE. -*******************************************************************************************************/ - - -package org.testar.monkey.alayer.linux.gtk3; - - -import org.bridj.BridJ; -import org.bridj.Pointer; -import org.bridj.ann.Library; - -import java.io.IOException; - - -/** - * Implementation of GTK+ 3. - */ -@Library("libgtk-3") -public class LibGtk3 { - - - static{ - try { - BridJ.getNativeLibrary("libgtk-3"); - } catch (IOException e) { - e.printStackTrace(); - } - BridJ.register(); - } - - - //*** GDK General ***\\ - - - /** - * Initializes the GDK library and connects to the windowing system. If initialization fails, - * a warning message is output and the application terminates with a call to exit(1). - * Any arguments used by GDK are removed from the array and argc and argv are updated accordingly. - * GTK+ initializes GDK in gtk_init() and so this function is not usually needed by GTK+ applications. - * @param argcPointer Pointer to the number of command line arguments. - * @param argvPtrToPtrToPtr Pointer to pointer to pointer to the array of command line arguments. - */ - public static native void gdk_init(long argcPointer, long argvPtrToPtrToPtr); - - - - //*** GTK Main ***\\ - - - /** - * Checks if any events are pending. - * This can be used to update the GUI and invoke timeouts etc. while doing some time intensive computation. - * Example: Updating the GUI during a long computation. - * @return Returns true if any events are pending, false otherwise. - */ - public static native boolean gtk_events_pending(); - - - /** - * Runs a single iteration of the main loop. - * If no events are waiting to be processed GTK+ will block until the next event is noticed. If you don't want to - * block then pass false for blocking or check if any events are pending with pending() first. - * @return true if quit() has been called for the innermost main loop. - */ - public static native boolean gtk_main_iteration(); - - - - //*** GDK Display ***\\ - - - /** - * Opens a display. - * @param displayName The name of the display to open. - * @return Returns a GdkDisplay, or NULL if the display could not be opened. - */ - public static native long gdk_display_open(Pointer displayName); - - - /** - * Gets the default GdkDisplay. This is a convenience function for: - * gdk_display_manager_get_default_display (gdk_display_manager_get()). - * @return Returns a GdkDisplay, or NULL if there is no default display. - */ - public static native long gdk_display_get_default(); - - - /** - * Gets the name of the display. - * @param displayPointer A pointer to a display object. - * @return Returns a string representing the display name. This string is owned by GDK and - * should not be modified or freed. - */ - public static native Pointer gdk_display_get_name(long displayPointer); - - - /** - * Closes the connection to the windowing system for the given display, and cleans up associated resources. - * @param displayPointer A pointer to a display object. - */ - public static native void gdk_display_close(long displayPointer); - - - /** - * Finds out if the display has been closed. - * @param displayPointer A pointer to a display object. - * @return True if the display is closed; False otherwise. - */ - public static native boolean gdk_display_is_closed(long displayPointer); - - - /** - * Get the default GdkScreen for display. - * @param displayPointer A pointer to a display object. - * @return The default GdkScreen object for display. - */ - public static native long gdk_display_get_default_screen(long displayPointer); - - -// /** -// * Gets the number of monitors that belong to display. -// * The returned number is valid until the next emission of the "monitor-added" or "monitor-removed" signal. -// * @param displayPointer The default GdkScreen object for display. -// * @return Returns the number of monitors. -// */ -// public static native int gdk_display_get_n_monitors(long displayPointer); -// -// -// /** -// * Gets a monitor associated with this display. -// * @param displayPointer The default GdkScreen object for display. -// * @param monitorIndex The index of the monitor to retrieve. -// * @return Returns (a pointer to) the GdkMonitor, or NULL if monitor_num is not a valid monitor number. -// */ -// public static native long gdk_display_get_monitor(long displayPointer, int monitorIndex); - - - - // /*** GDK DisplayManager ***\ - - - /** - * Gets the singleton GdkDisplayManager object. - * When called for the first time, this function consults the GDK_BACKEND environment variable to find out which of - * the supported GDK backends to use (in case GDK has been compiled with multiple backends). Applications can use - * gdk_set_allowed_backends() to limit what backends can be used. - * @return The global GdkDisplayManager singleton; gdk_parse_args(), gdk_init(), or gdk_init_check() - * must have been called first. - */ - public static native long gdk_display_manager_get(); - - - /** - * Gets the default GdkDisplay. - * @param displayManagerPointer A pointer to a DisplayManager object. - * @return Returns a GdkDisplay, or NULL if there is no default display. - */ - public static native long gdk_display_manager_get_default_display(long displayManagerPointer); - - - - //*** GDK Monitor ***\\ - - - - - // ** GDK Screen ***\\ - - - /** - * Gets the root window of screen. - * @param screenPointer A pointer to a screen object. - * @return Returns (a pointer to) the root window. - */ - public static native long gdk_screen_get_root_window(long screenPointer); - - - /** - * Gets the width of screen in pixels. The returned size is in "application pixels", not in "device pixels" - * (see gdk_screen_get_monitor_scale_factor()). - * @param screenPointer A pointer to the screen to get the width for. - * @return Returns the width of screen in pixels. - */ - public static native int gdk_screen_get_width(long screenPointer); - - - /** - * Gets the height of screen in pixels. The returned size is in "application pixels", not in "device pixels" - * (see gdk_screen_get_monitor_scale_factor()). - * @param screenPointer A pointer to the screen to get the height for. - * @return Returns the height of screen in pixels. - */ - public static native int gdk_screen_get_height(long screenPointer); - - - /** - * Obtains a list of all toplevel windows known to GDK on the screen screen . A toplevel window is a child of - * the root window (see gdk_get_default_root_window()). - * The returned list should be freed with g_list_free(), but its elements need not be freed. - * @param screenPointer A pointer to the screen to get the height for. - * @return Returns a list of toplevel windows, free with g_list_free(). - */ - public static native long gdk_screen_get_toplevel_windows(long screenPointer); - - -} diff --git a/linux/src/org/testar/monkey/alayer/linux/libwnck/LibWnck.java b/linux/src/org/testar/monkey/alayer/linux/libwnck/LibWnck.java deleted file mode 100644 index d05f76bde..000000000 --- a/linux/src/org/testar/monkey/alayer/linux/libwnck/LibWnck.java +++ /dev/null @@ -1,178 +0,0 @@ -/*************************************************************************************************** -* -* Copyright (c) 2017 Open Universiteit - www.ou.nl -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, -* this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the copyright holder nor the names of its -* contributors may be used to endorse or promote products derived from -* this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -* POSSIBILITY OF SUCH DAMAGE. -*******************************************************************************************************/ - - -package org.testar.monkey.alayer.linux.libwnck; - -import org.bridj.BridJ; -import org.bridj.Pointer; -import org.bridj.ann.Library; - -import java.io.IOException; - - -/** - * LibWnck implementation - native method link. - */ -@Library("libwnck-3") -public class LibWnck { - - - static{ - try { - BridJ.getNativeLibrary("libwnck-3"); - } catch (IOException e) { - e.printStackTrace(); - } - BridJ.register(); - } - - - - //*** WnckScreen ***\\ - - - /** - * Gets the default WnckScreen on the default display. - * @return Returns the default WnckScreen. The returned WnckScreen is owned by libwnck and must not be - * referenced or unreferenced. - */ - public static native long wnck_screen_get_default(); - - - /** - * Gets the width of screen. - * @param screenPointer Pointer to a WnckScreen object. - * @return Returns the width of screen. - */ - public static native int wnck_screen_get_width(long screenPointer); - - - /** - * Gets the height of screen. - * @param screenPointer Pointer to a WnckScreen object. - * @return Returns the height of screen. - */ - public static native int wnck_screen_get_height(long screenPointer); - - - /** - * Synchronously and immediately updates the list of WnckWindow on screen. This bypasses the standard update - * mechanism, where the list of WnckWindow is updated in the idle loop. - * This is usually a bad idea for both performance and correctness reasons (to get things right, - * you need to write model-view code that tracks changes, not get a static list of open windows). However, - * this function can be useful for small applications that just do something and then exit. - * @param screenPointer Pointer to a WnckScreen object. - */ - public static native void wnck_screen_force_update(long screenPointer); - - - /** - * Gets the active WnckWindow on screen. May return NULL sometimes, since not all window managers - * guarantee that a window is always active. - * @param screenPointer Pointer to a WnckScreen object. - * @return the active WnckWindow on screen, or NULL. The returned WnckWindow is owned by libwnck and must not be - * referenced or unreferenced. - */ - public static native long wnck_screen_get_active_window(long screenPointer); - - - /** - * Gets the (pointer to a) list of WnckWindow on screen . The list is not in a defined order, but should be - * "stable" (windows should not be reordered in it). However, the stability of the list is - * established by the window manager, so don't blame libwnck if it breaks down. - * @param screenPointer Pointer to a WnckScreen object. - * @return Returns the list of WnckWindow on screen , or NULL if there is no window on screen. - * The list should not be modified nor freed, as it is owned by screen. - */ - public static native long wnck_screen_get_windows(long screenPointer); - - - - //*** WnckWindow ***\\ - - - /** - * Gets a preexisting WnckWindow for the X window xwindow. This will not create a WnckWindow if none exists. - * The function is robust against bogus window IDs. - * @param xWindowId An X window ID. - * @return Returns the WnckWindow for xwindow . The returned WnckWindow is owned by libwnck and must - * not be referenced or unreferenced. - */ - public static native long wnck_window_get(long xWindowId); - - - /** - * Checks whether or not window has a name. wnck_window_get_name() will always return some value, even if - * window has no name set; wnck_window_has_name() can be used to tell if that name is real or not. - * For icons titles, use wnck_window_has_icon_name() instead. - * @param windowPointer Pointer to a WnckWindow object. - * @return Returns TRUE if wnck_window_get_name() returns window 's name, FALSE if it returns a fallback name. - */ - public static native boolean wnck_window_has_name(long windowPointer); - - - /** - * Gets the name of window, as it should be displayed in a pager or tasklist. Always returns some value, - * even if window has no name set; use wnck_window_has_name() if you need to know whether the returned name is - * "real" or not. For icons titles, use wnck_window_get_icon_name() instead. - * @param windowPointer Pointer to a WnckWindow object. - * @return Returns the name of window , or a fallback name if no name is available. - */ - public static native Pointer wnck_window_get_name(long windowPointer); - - - /** - * Gets the process ID of window. - * @param windowPointer Pointer to a WnckWindow object. - * @return Returns the process ID of window, or 0 if none is available. - */ - public static native int wnck_window_get_pid(long windowPointer); - - - /** - * Asks the window manager to make window the active window. The window manager may choose to raise window along - * with focusing it, and may decide to refuse the request (to not steal the focus if there is a more recent user - * activity, for example). - * This function existed before 2.10, but the timestamp argument was missing in earlier versions. - * @param windowPointer Pointer to a WnckWindow object. - * @param timestamp The X server timestamp of the user interaction event that caused this call to occur. - */ - public static native void wnck_window_activate(long windowPointer, int timestamp); - - - /** - * Gets whether window is the active window on its WnckScreen. - * @param windowPointer Pointer to a WnckWindow object. - * @return Returns TRUE if window is the active window on its WnckScreen, FALSE otherwise. - */ - public static native boolean wnck_window_is_active(long windowPointer); - - -} diff --git a/linux/src/org/testar/monkey/alayer/linux/libwnck/WnckWindow.java b/linux/src/org/testar/monkey/alayer/linux/libwnck/WnckWindow.java deleted file mode 100644 index 7183294eb..000000000 --- a/linux/src/org/testar/monkey/alayer/linux/libwnck/WnckWindow.java +++ /dev/null @@ -1,152 +0,0 @@ -/*************************************************************************************************** -* -* Copyright (c) 2017 Open Universiteit - www.ou.nl -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, -* this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the copyright holder nor the names of its -* contributors may be used to endorse or promote products derived from -* this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -* POSSIBILITY OF SUCH DAMAGE. -*******************************************************************************************************/ - - -package org.testar.monkey.alayer.linux.libwnck; - - -import org.testar.monkey.alayer.linux.util.BridJHelper; - - -/** - * Java implementation of an WnckWindow object. - */ -public class WnckWindow { - - - //region Properties - - - private long _windowPtr; - public long windowPtr() { - return _windowPtr; - } - - - private boolean _hasName; - public boolean hasName() { return LibWnck.wnck_window_has_name(_windowPtr); } - - - private String _name; - public String name() { - return BridJHelper.convertToString(LibWnck.wnck_window_get_name(_windowPtr)); - } - - - private int _pid; - public int pid() { return LibWnck.wnck_window_get_pid(_windowPtr); } - - - //endregion - - - //region Constructors - - - /** - * Default empty constructor. - */ - private WnckWindow() { - - } - - - /** - * Creates a new instance of an WnckWindow object from a pointer. - * @param wndwPtr Pointer to the WnckWindow object. - * @return A Java instance of an WnckWindow object. - */ - public static WnckWindow CreateInstance(long wndwPtr) { - - - if (wndwPtr == 0) { - return null; - } - - - // Create a new instance. - WnckWindow wObj = new WnckWindow(); - - - // Fill the instance's properties. - //fillInstance(windowPtr, wObj,); - wObj._windowPtr = wndwPtr; - - - return wObj; - - } - - - /** - * Fills an WnckWindow object's information. - * @param wndwPtr Pointer to the WnckWindow object. - * @param wObj The Java instance of an WnckWindow object. - */ - private static void fillInstance(long wndwPtr, WnckWindow wObj) { - - - // Fill the properties with the information. - wObj._windowPtr = wndwPtr; - wObj._hasName = LibWnck.wnck_window_has_name(wndwPtr); - wObj._name = BridJHelper.convertToString(LibWnck.wnck_window_get_name(wndwPtr)); - wObj._pid = LibWnck.wnck_window_get_pid(wndwPtr); - - - } - - - //endregion - - - /** - * Fills the information for this object. - */ - public void fillDebug() { - fillInstance(_windowPtr, this); - } - - - //region Object overrides - - - /** - * Returns a string representation of an WnckWindow object. - * @return Returns a string representation of an WnckWindow object. - */ - @Override - public String toString() { - return "Name: " + _name; - } - - - //endregion - - -} diff --git a/linux/src/org/testar/monkey/alayer/linux/util/BridJHelper.java b/linux/src/org/testar/monkey/alayer/linux/util/BridJHelper.java deleted file mode 100644 index 721e3d9f2..000000000 --- a/linux/src/org/testar/monkey/alayer/linux/util/BridJHelper.java +++ /dev/null @@ -1,71 +0,0 @@ -/*************************************************************************************************** -* -* Copyright (c) 2017 Open Universiteit - www.ou.nl -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, -* this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the copyright holder nor the names of its -* contributors may be used to endorse or promote products derived from -* this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -* POSSIBILITY OF SUCH DAMAGE. -*******************************************************************************************************/ - - -package org.testar.monkey.alayer.linux.util; - - -import org.bridj.Pointer; - - -/** - * Class to help with BridJ functionality. - */ -public class BridJHelper { - - - private static final String EmptyString = ""; - - - /** - * Converts a pointer to a string to a String. - * @param stringPointer The pointer to the string. - * @return The string the pointer points to. - */ - public static String convertToString(Pointer stringPointer) { - - if (stringPointer == null) { - return EmptyString; - } - - return stringPointer.getCString(); - } - - - /** - * Converts a String to a pointer to a string. - * @param str The string to get a pointer to. - * @return The pointer to a String. - */ - public static Pointer convertToPointer(String str) { - return Pointer.pointerToCString(str); - } - - -} diff --git a/linux/src/org/testar/monkey/alayer/linux/util/GdkHelper.java b/linux/src/org/testar/monkey/alayer/linux/util/GdkHelper.java deleted file mode 100644 index c8d862be6..000000000 --- a/linux/src/org/testar/monkey/alayer/linux/util/GdkHelper.java +++ /dev/null @@ -1,83 +0,0 @@ -/*************************************************************************************************** -* -* Copyright (c) 2017 Open Universiteit - www.ou.nl -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, -* this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the copyright holder nor the names of its -* contributors may be used to endorse or promote products derived from -* this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -* POSSIBILITY OF SUCH DAMAGE. -*******************************************************************************************************/ - - -package org.testar.monkey.alayer.linux.util; - - -import org.testar.monkey.alayer.Rect; -import org.testar.monkey.alayer.linux.gtk3.LibGtk3; - - -/** - * Utility class to help with GDK functionality. - */ -public class GdkHelper { - - - private static final String _defaultDisplay = ":0"; - - - /** - * Gets the bounding box of the primary screen of the default display. - * @return The bounding box of the primary screen of the default display. - */ - public static Rect getScreenBoundingBox() { - - - // Open the default display. - long displayPointer = LibGtk3.gdk_display_open(BridJHelper.convertToPointer(_defaultDisplay)); - if (displayPointer <= 0) { - return Rect.from(0, 0, 0, 0); - } - - - // Get the primary screen. - long screenPointer = LibGtk3.gdk_display_get_default_screen(displayPointer); - if (screenPointer <= 0) { - return Rect.from(0, 0, 0, 0); - } - - - // This code should not be used when using GTK 3.22 or higher - it's deprecated. - int width = LibGtk3.gdk_screen_get_width(screenPointer); - int height = LibGtk3.gdk_screen_get_height(screenPointer); - - - LibGtk3.gdk_display_close(displayPointer); - - - return Rect.from(0, 0, width, height); - - - } - - - -} diff --git a/linux/src/org/testar/monkey/alayer/linux/util/JavaHelper.java b/linux/src/org/testar/monkey/alayer/linux/util/JavaHelper.java deleted file mode 100644 index d466ed268..000000000 --- a/linux/src/org/testar/monkey/alayer/linux/util/JavaHelper.java +++ /dev/null @@ -1,99 +0,0 @@ -/*************************************************************************************************** -* -* Copyright (c) 2017 Open Universiteit - www.ou.nl -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, -* this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the copyright holder nor the names of its -* contributors may be used to endorse or promote products derived from -* this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -* POSSIBILITY OF SUCH DAMAGE. -*******************************************************************************************************/ - - -package org.testar.monkey.alayer.linux.util; - - -/** - * Some Java utility functions. - */ -public class JavaHelper { - - - /** - * Tries to parse a String to an int. - * @param value The string to parse as an int. - * @return True if the string can be parsed as an int; False otherwise. - */ - public static boolean tryParseInt(String value) { - try { - //noinspection ResultOfMethodCallIgnored - Integer.parseInt(value); - return true; - } catch (NumberFormatException e) { - return false; - } - } - - - /** - * Tries to parse a String to an int. - * @param value The string to parse as an int. - * @return True if the string can be parsed as an int; False otherwise. - */ - public static boolean tryParseDouble(String value) { - try { - //noinspection ResultOfMethodCallIgnored - Double.parseDouble(value); - return true; - } catch (NumberFormatException e) { - return false; - } - } - - - /*** - * Checks to see if a string is null or empty. - * @param s string to check. - * @return true if null or empty; otherwise false. - */ - public static boolean isNullOrEmpty(String s) { - return s == null || s.length() == 0; - } - - - /*** - * Checks if a string is null or empty or contains only whitespace. - * @param s string to check. - * @return true if null or emptry or only whitespace; otherwise false. - */ - public static boolean isNullOrWhitespace(String s) { - if (isNullOrEmpty(s)) - return true; - for (int i = 0; i < s.length(); i++) { - if (!Character.isWhitespace(s.charAt(i))) { - return false; - } - } - return true; - } - - -} diff --git a/linux/src/org/testar/monkey/alayer/linux/util/xdotools.java b/linux/src/org/testar/monkey/alayer/linux/util/xdotools.java deleted file mode 100644 index 63cadc0a2..000000000 --- a/linux/src/org/testar/monkey/alayer/linux/util/xdotools.java +++ /dev/null @@ -1,119 +0,0 @@ -/*************************************************************************************************** -* -* Copyright (c) 2017 Open Universiteit - www.ou.nl -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, -* this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the copyright holder nor the names of its -* contributors may be used to endorse or promote products derived from -* this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -* POSSIBILITY OF SUCH DAMAGE. -*******************************************************************************************************/ - - -package org.testar.monkey.alayer.linux.util; - - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; - - -/** - * Utility class that provides functionality to work with xprop. - */ -public class xdotools { - - private static final String PIDFromActiveWindow = "xdotool getactivewindow getwindowpid"; - private static final String NameFromActiveWindow = "xdotool getactivewindow getwindowname"; - - - /** - * Tries to retrieve the PID from the currently active window (application). - * @return If successful the PID of the currently active window (application); -1 otherwise. - */ - public static int getPIDFromActiveWindow() { - - - try { - - - // Run the command. - Process p = Runtime.getRuntime().exec(PIDFromActiveWindow); - - - // Get the stream to read the command output from. - BufferedReader commandOutputReader = new BufferedReader(new InputStreamReader(p.getInputStream())); - - - // Read the output as lines - should only be one. - String outputLine = commandOutputReader.readLine(); - - if (!JavaHelper.isNullOrWhitespace(outputLine) && JavaHelper.tryParseInt(outputLine)) { - return Integer.parseInt(outputLine); - } - - - System.out.println("Could not parse '" + outputLine + "' to a PID."); - - - return -1; - - - } catch (IOException e) { - return -1; - } - - - } - - - /** - * Tries to retrieve the name of the currently active window (application). - * @return If successful the name of the currently active window (applicaiton); null otherwise. - */ - public static String getNameFromActiveWindow() { - - - try { - - - // Run the command. - Process p = Runtime.getRuntime().exec(NameFromActiveWindow); - - - // Get the stream to read the command output from. - BufferedReader commandOutputReader = new BufferedReader(new InputStreamReader(p.getInputStream())); - - - // Read the output as lines - should only be one. - return commandOutputReader.readLine(); - - - - } catch (IOException e) { - return null; - } - - - } - - -} diff --git a/linux/src/org/testar/monkey/alayer/linux/xlib/LibX11.java b/linux/src/org/testar/monkey/alayer/linux/xlib/LibX11.java deleted file mode 100644 index 34089cdb3..000000000 --- a/linux/src/org/testar/monkey/alayer/linux/xlib/LibX11.java +++ /dev/null @@ -1,187 +0,0 @@ -/*************************************************************************************************** -* -* Copyright (c) 2017 Open Universiteit - www.ou.nl -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, -* this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the copyright holder nor the names of its -* contributors may be used to endorse or promote products derived from -* this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -* POSSIBILITY OF SUCH DAMAGE. -*******************************************************************************************************/ - - -package org.testar.monkey.alayer.linux.xlib; - -import org.bridj.BridJ; -import org.bridj.Pointer; -import org.bridj.ann.Library; - -import java.io.IOException; - - -/** - * Implementation of LibX11. - */ -@Library("libX11") -public class LibX11 { - - - static{ - try { - BridJ.getNativeLibrary("libX11"); - } catch (IOException e) { - e.printStackTrace(); - } - BridJ.register(); - } - - - //*** libX11 ***\\ - - - /** - * Opens a connection to the X server that controls a display. - * - * @param displayName Specifies the hardware display name, which determines the display and communications - * domain to be used. On a POSIX-conformant system, if the display_name is NULL, - * it defaults to the value of the DISPLAY environment variable. - * @return Returns a (pointer to a) Display structure that serves as the connection to the X server and that - * contains all the information about that X server. - */ - public static native long XOpenDisplay(Pointer displayName); - - - /** - * Closes the connection to the X server for the display specified in the Display structure and destroys all - * windows, resource IDs (Window, Font, Pixmap, Colormap, Cursor, and GContext), or other resources that - * the client has created on this display, unless the close-down mode of the resource has been changed - * (see XSetCloseDownMode()). - * @param displayPtr Specifies the connection to the X server in (a pointer to) a Display structure. - */ - public static native void XCloseDisplay(long displayPtr); - - - /** - * Returns the string that was passed to XOpenDisplay() when the current display was opened. - * @param displayPtr Specifies the connection to the X server in (a pointer to) a Display structure. - * @return Returns the string that was passed to XOpenDisplay() when the current display was opened. - * On POSIX-conformant systems, if the passed string was NULL, these return the value of - * the DISPLAY environment variable when the current display was opened. - */ - public static native Pointer XDisplayString(long displayPtr); - - - /** - * Returns an integer that describes the height of the screen in pixels. - * @param displayPtr Specifies the connection to the X server in (a pointer to) a Display structure. - * @param screenNumber Specifies the appropriate screen number on the host X server. - * @return Returns an integer that describes the height of the screen in pixels. - */ - public static native int XDisplayHeight(long displayPtr, int screenNumber); - - - /** - * Returns an integer that describes the width of the screen in pixels. - * @param displayPtr Specifies the connection to the X server in (a pointer to) a Display structure. - * @param screenNumber Specifies the appropriate screen number on the host X server. - * @return Returns an integer that describes the width of the screen in pixels. - */ - public static native int XDisplayWidth(long displayPtr, int screenNumber); - - - /** - * Returns the number of available screens. - * @param displayPtr Specifies the connection to the X server in (a pointer to) a Display structure. - * @return Returns the number of available screens. - */ - public static native int XScreenCount(long displayPtr); - - - /** - * Returns the default screen number referenced by the XOpenDisplay() function. - * @param displayPtr Specifies the connection to the X server in (a pointer to) a Display structure. - * @return Returns the default screen number referenced by the XOpenDisplay() function. - */ - public static native int XDefaultScreen(long displayPtr); - - - /** - * Returns the root window. - * @param displayPtr Specifies the connection to the X server in (a pointer to) a Display structure. - * @param screenNumber Specifies the appropriate screen number on the host X server. - * @return Returns the root window. - */ - public static native int XRootWindow(long displayPtr, int screenNumber); - - - /** - * The XInternAtom() function returns the atom identifier associated with the specified atom_name string. If - * only_if_exists is False, the atom is created if it does not exist. Therefore, XInternAtom() can return None. - * If the atom name is not in the Host Portable Character Encoding, the result is implementation dependent. - * Uppercase and lowercase matter; the strings ``thing'', ``Thing'', and ``thinG'' all designate different atoms. - * The atom will remain defined even after the client's connection closes. It will become undefined only when the - * last connection to the X server closes. - * @param displayPtr Specifies the connection to the X server in (a pointer to) a Display structure. - * @param atomName Name of the Atom to find. - * @param onlyIfExists Specifies a Boolean value that indicates whether the atom must be created. - * @return The Atom requested. - */ - public static native long XInternAtom(long displayPtr, Pointer atomName, boolean onlyIfExists); - - - /** - * The XGetWindowProperty() function returns the actual type of the property; the actual format of the property; - * the number of 8-bit, 16-bit, or 32-bit items transferred; the number of bytes remaining to be read in the - * property; and a pointer to the data actually returned. - * @param displayPtr Specifies the connection to the X server. - * @param w Specifies the window whose property you want to obtain. - * @param property Specifies the property name. - * @param offset Specifies the offset in the specified property (in 32-bit quantities) where the data is to be retrieved. - * @param length Specifies the length in 32-bit multiples of the data to be retrieved. - * @param delete Specifies a Boolean value that determines whether the property is deleted. - * @param reqType Specifies the atom identifier associated with the property type or AnyPropertyType. - * @param actualTypeReturnPtr Returns the atom identifier that defines the actual type of the property. - * @param actualFormatReturnPtr Returns the actual format of the property. - * @param itemsReturnPtr Returns the actual number of 8-bit, 16-bit, or 32-bit items stored in the prop_return data. - * @param bytesAfterReturnPtr Returns the number of bytes remaining to be read in the property if a partial read was performed. - * @param propReturnPtrToPtr Returns the data in the specified format. - * @return The function returns Success if it executes successfully. - */ - public static native int XGetWindowProperty(long displayPtr, long w, long property, long offset, long length, - boolean delete, long reqType, long actualTypeReturnPtr, - int actualFormatReturnPtr, long itemsReturnPtr, long bytesAfterReturnPtr, - long propReturnPtrToPtr); - - - /** - * The XRaiseWindow() function raises the specified window to the top of the stack so that no - * sibling window obscures it. - * @param displayPtr Specifies the connection to the X server in (a pointer to) a Display structure. - * @param windowId Specifies the window. - */ - public static native void XRaiseWindow(long displayPtr, long windowId); - - - public static native long XSendEvent(long displaytPtr, long windowId, boolean propagate, - long eventMask, long eventSend); - - -} diff --git a/linux/src/org/testar/monkey/example/linux/ClickThroughWindow.java b/linux/src/org/testar/monkey/example/linux/ClickThroughWindow.java deleted file mode 100644 index d234b11fc..000000000 --- a/linux/src/org/testar/monkey/example/linux/ClickThroughWindow.java +++ /dev/null @@ -1,104 +0,0 @@ -/*************************************************************************************************** -* -* Copyright (c) 2017 Open Universiteit - www.ou.nl -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, -* this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the copyright holder nor the names of its -* contributors may be used to endorse or promote products derived from -* this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -* POSSIBILITY OF SUCH DAMAGE. -*******************************************************************************************************/ - -package org.testar.monkey.example.linux; - -import javax.swing.*; -import java.awt.*; - -import static java.awt.GraphicsDevice.WindowTranslucency.TRANSLUCENT; - -public class ClickThroughWindow { - - public static void main(String[] args) { - - // Determine if the GraphicsDevice supports translucency. - GraphicsEnvironment ge = - GraphicsEnvironment.getLocalGraphicsEnvironment(); - GraphicsDevice gd = ge.getDefaultScreenDevice(); - - //If translucent windows aren't supported, exit. - if (!gd.isWindowTranslucencySupported(TRANSLUCENT)) { - System.err.println( - "Translucency is not supported"); - System.exit(0); - } - - new ClickThroughWindow(); - } - - - public ClickThroughWindow() { - EventQueue.invokeLater(() -> { - try { - UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); - } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { - ex.printStackTrace(); - } - - JFrame frame = new JFrame("Testing"); - frame.setUndecorated(true); - frame.setResizable(false); - frame.setType(Window.Type.UTILITY); - frame.setBackground(new Color(0, 0, 0, 0)); - frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - frame.add(new TestPane()); - frame.setAlwaysOnTop(true); - frame.pack(); - frame.setLocationRelativeTo(null); - frame.setVisible(true); - }); - } - - public class TestPane extends JPanel { - - private static final long serialVersionUID = 4544911864979860310L; - - public TestPane() { - setOpaque(false); - } - - @Override - public Dimension getPreferredSize() { - return new Dimension(200, 200); - } - - @Override - protected void paintComponent(Graphics g) { - super.paintComponent(g); - Graphics2D g2d = (Graphics2D) g.create(); - g2d.setColor(getBackground()); - g2d.setColor(Color.RED); - g2d.drawRect(0, 0, getWidth() - 1, getHeight() - 1); - g2d.dispose(); - } - - } - -} diff --git a/linux/src/org/testar/monkey/example/linux/Main.java b/linux/src/org/testar/monkey/example/linux/Main.java deleted file mode 100644 index 65663edbd..000000000 --- a/linux/src/org/testar/monkey/example/linux/Main.java +++ /dev/null @@ -1,156 +0,0 @@ -/*************************************************************************************************** -* -* Copyright (c) 2017 Open Universiteit - www.ou.nl -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, -* this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the copyright holder nor the names of its -* contributors may be used to endorse or promote products derived from -* this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -* POSSIBILITY OF SUCH DAMAGE. -*******************************************************************************************************/ - -package org.testar.monkey.example.linux; - - -import org.testar.monkey.alayer.linux.atspi.LibAtSpi; -import org.testar.monkey.alayer.linux.LinuxProcess; - - -/** - * Test class to test Linux functionality. - */ -public class Main { - - - private static final String ApplicationPath_GEdit = "/usr/bin/gedit"; - - - /** - * Entry-point for the test class. - * @param args command-line arguments. - */ - public static void main(String[] args) { - - //launchApplication(); - //testAtSpi(); - //testLibX11(); - - } - - - /** - * Tests launching a Linux application. - */ - private static void launchApplication(){ - - - LinuxProcess lp = LinuxProcess.fromExecutable(ApplicationPath_GEdit); - - - if (lp == null) { - System.out.println("Failed to launch the requested application."); - } - - - - } - - - /** - * Tests AT-SPI functions. - */ - private static void testAtSpi() { - - System.out.println("Desktop count: " + LibAtSpi.atspi_get_desktop_count()); - - } - - -// /** -// * Tests XLib functions. -// */ -// private static void testLibX11() { -// -// -// // First, get a pointer to a Display structure for the current machine; when null is used the -// // environment variable DISPLAY is used which translates to ':0'. -// long displayPointer = LibX11.XOpenDisplay(null); -// -// -// if (displayPointer == 0) { -// System.out.println("Cannot open the display!"); -// return; -// } -// -// -// // Get the string used to retrieve the display. -// Pointer displayStringPtr = LibX11.XDisplayString(displayPointer); -// System.out.println("Display opened with string: '" + displayStringPtr.getCString() + "'."); -// -// -// // Get the default screen number of the current display. -// int defaultScreenNumber = LibX11.XDefaultScreen(displayPointer); -// System.out.println("Default display screen number: '" + defaultScreenNumber + "'."); -// -// -// // Get the dimensions of the display. -// int displayHeighth = LibX11.XDisplayHeight(displayPointer, defaultScreenNumber); -// int displayWidth = LibX11.XDisplayWidth(displayPointer, defaultScreenNumber); -// System.out.println("Display dimensions: '" + displayWidth + "x" + displayHeighth + "'."); -// -// -// // Get the number of screens connected to the display adapter. -// int screenCount = LibX11.XScreenCount(displayPointer); -// System.out.println("Number of screens connected to the display adapter: '" + screenCount + "'."); -// -// -// -// // Now get the RootWindow. -// // TODO: get/create a Window object or check if the returned pointer can be used somehow. -// long rootWindow = LibX11.XRootWindow(displayPointer, defaultScreenNumber); -// -// -// if (rootWindow == 0) { -// -// } -// -// -// // TODO: Find the Window for a given PID. -// -// -// -// -// // TODO: Bring the Window to the foreground - most likely an XSendEvent is necessary, raising doesn't give focus or unhide from mimimize. -// // Bring the window given its WindowId to the foreground. -// //LibX11.XRaiseWindow(displayPointer, 65011747); // 67108874 -// -// -// -// // Close connection to the opened display. -// LibX11.XCloseDisplay(displayPointer); -// System.out.println("Display closed!"); -// -// -// } - - - -} diff --git a/linux/src/org/testar/monkey/example/tests/LibAtSpiTests.java b/linux/src/org/testar/monkey/example/tests/LibAtSpiTests.java deleted file mode 100644 index c52d324ec..000000000 --- a/linux/src/org/testar/monkey/example/tests/LibAtSpiTests.java +++ /dev/null @@ -1,342 +0,0 @@ -/*************************************************************************************************** -* -* Copyright (c) 2017 Open Universiteit - www.ou.nl -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, -* this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the copyright holder nor the names of its -* contributors may be used to endorse or promote products derived from -* this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -* POSSIBILITY OF SUCH DAMAGE. -*******************************************************************************************************/ - -package org.testar.monkey.example.tests; - - -import org.bridj.Pointer; -import org.testar.monkey.alayer.linux.atspi.LibAtSpi; -import org.testar.monkey.alayer.linux.LinuxProcess; -import org.testar.monkey.alayer.linux.atspi.AtSpiAccessible; -import org.testar.monkey.alayer.linux.atspi.TreeWalker; -import org.testar.monkey.alayer.linux.atspi.enums.AtSpiRoles; -import org.testar.monkey.alayer.linux.atspi.enums.AtSpiStateTypes; -import org.junit.jupiter.api.Test; - -import java.util.List; - -import static org.junit.jupiter.api.Assertions.*; - - -/** - * Unit tests for working with the AT-SPI API. - */ -public class LibAtSpiTests { - - - private static final String ApplicationPath_GEdit = "/usr/bin/gedit"; - - - @Test - public void DesktopMethods() { - - - // Get the desktop count. - int desktopCount = LibAtSpi.atspi_get_desktop_count(); - assertEquals(1, desktopCount); - - - // Get a pointer to the desktop accessible object. - long desktopPointer = LibAtSpi.atspi_get_desktop(0); - assertEquals(true, desktopPointer > 0); - System.out.println("Desktop pointer: " + desktopPointer); - - - // Get the name of the accessible object - for now the pointer to pointer for an error object can be null. - Pointer name = LibAtSpi.atspi_accessible_get_name(desktopPointer, 0); - assertEquals("main", name.getCString()); - - - Pointer desc = LibAtSpi.atspi_accessible_get_description(desktopPointer, 0); - assertEquals("", desc.getCString()); - - - // Test the child count - get a reference for the current state. - int childCount = LibAtSpi.atspi_accessible_get_child_count(desktopPointer, 0); - - - // Launch a new application. - LinuxProcess gedit = LinuxProcess.fromExecutable(ApplicationPath_GEdit); - - - // Short pause to give the application time to start. - try { - Thread.sleep(200); - } catch (InterruptedException e) { - e.printStackTrace(); - } - - - // Take a new snapshot and compare them. - int childCountAfterLaunch = LibAtSpi.atspi_accessible_get_child_count(desktopPointer, 0); - assertEquals(childCount + 1, childCountAfterLaunch); - - - // Get the UI role name of the accessible object. - Pointer roleName = LibAtSpi.atspi_accessible_get_role_name(desktopPointer, 0); - assertEquals("desktop frame", roleName.getCString()); - - - // Get the role - method returns an int. To cast it to the corresponding enum value use the returned value as the index - // for the enum's values array. - AtSpiRoles role = AtSpiRoles.values()[LibAtSpi.atspi_accessible_get_role(desktopPointer, 0)]; - assertEquals(AtSpiRoles.DesktopFrame, role); - - - - // Test the children pointers. - List children = AtSpiAccessible.getAccessibleChildrenPtrs(desktopPointer); - assertEquals(childCount + 1, children.size()); - - - // Test the children as AtSpiAccessible instances. - List childrenExt = AtSpiAccessible.getAccessibleChildren(desktopPointer); - assertEquals(childCount + 1, childrenExt.size()); - - - List geditChildren; - long geditActionPtr = 0; - - - // Test gedit children's state. - for (AtSpiAccessible a : childrenExt) { - if (a.name().equals("gedit")){ - - geditChildren = AtSpiAccessible.getAccessibleChildren(a); - assertEquals("frame", geditChildren.get(0).roleName()); - assertEquals(true, geditChildren.get(0).states().isActive()); - - geditActionPtr = LibAtSpi.atspi_accessible_get_action_iface(geditChildren.get(0).accessiblePtr()); - - } - } - - - // Test if all children can be found for an AtSpiAccessible object. - AtSpiAccessible desktopTree = TreeWalker.createAccessibleTree(desktopPointer, true); - assertNotNull(desktopTree); - - List ch = desktopTree.children(); - for (AtSpiAccessible a : ch) { - a.retrieveAccessibleInfo(); - } - - - // The current implementation is too heavy to get the entire tree with all information for the entire machine - apparently... - desktopTree.retrieveAccessibleInfoTree(); - - - // Stop the application. - gedit.stop(); - - - // Short pause to give the application time to exit. - try { - Thread.sleep(200); - } catch (InterruptedException e) { - e.printStackTrace(); - } - - - } - - - @Test - public void GrabFocus() { - - - // Get a pointer to the desktop accessible object. - long desktopPointer = LibAtSpi.atspi_get_desktop(0); - assertEquals(true, desktopPointer > 0); - System.out.println("Desktop pointer: " + desktopPointer); - - - // Launch gedit. - LinuxProcess gedit = LinuxProcess.fromExecutable(ApplicationPath_GEdit); - - - // Short pause to give the application time to start. - try { - Thread.sleep(200); - } catch (InterruptedException e) { - e.printStackTrace(); - } - - - // Get a list of children. - List childrenExt = AtSpiAccessible.getAccessibleChildren(desktopPointer); - assertEquals(true, childrenExt.size() > 0); - - - // Find the gedit AtSpiAccessible. - AtSpiAccessible geditAcc = null; - - - for (AtSpiAccessible a : childrenExt) { - if (a.name().equals("gedit")){ - geditAcc = a; - } - } - assertNotNull(geditAcc); - - assert geditAcc != null; - assertEquals(true, geditAcc.accessiblePtr() > 0); - - - // Get the tree for gedit. - AtSpiAccessible geditTree = TreeWalker.createAccessibleTree(geditAcc.accessiblePtr(), false); - assertNotNull(geditTree); - - - // Find something focusable. - AtSpiAccessible focusable = TreeWalker.findFocusableApplicationElementNode(geditTree); - assertNotNull(focusable); - - - // Find a button. - AtSpiAccessible button = findButton(geditTree, AtSpiRoles.PushButton); - assertNotNull(button); - assert button != null; - button.retrieveAccessibleInfo(); - - - // Short pause to be able to hide gedit. - try { - Thread.sleep(5000); - } catch (InterruptedException e) { - e.printStackTrace(); - } - - - // Try to give gedit focus. - assert focusable != null; - assertNotNull(focusable.component()); - - List stateList = focusable.states().getStates(); - focusable.retrieveAccessibleInfo(); - - - System.out.println("BoundingBox Screen:" + focusable.component().extentsOnScreen().toString()); - System.out.println("BoundingBox Window:" + focusable.component().extentsOnWindow().toString()); - System.out.println("Position Screen:" + focusable.component().positionOnScreen().toString()); - System.out.println("Position Window:" + focusable.component().positionOnWindow().toString()); - System.out.println("Size:" + focusable.component().size().toString()); - - - boolean successfullFocus = focusable.component().grabFocus(); - assertEquals(true, successfullFocus); - - - // Wait a bit to let the user verify. - try { - Thread.sleep(5000); - } catch (InterruptedException e) { - e.printStackTrace(); - } - - - // Stop the application. - gedit.stop(); - - - // Short pause to give the application time to exit. - try { - Thread.sleep(200); - } catch (InterruptedException e) { - e.printStackTrace(); - } - - - } - - - /** - * Tries to find a button element. - * @param root Element to start from. - * @param buttonType Type of button as a role. - * @return An element that can is a button. - */ - private AtSpiAccessible findButton(AtSpiAccessible root, AtSpiRoles buttonType) { - - if (root.role() == buttonType) { - return root; - } - - - for (AtSpiAccessible a : root.children()) { - - if (a.role() == buttonType) { - return a; - } - - if (a.children().size() > 0) { - - AtSpiAccessible ret = findButton(a, buttonType); - - if (ret != null) { - return ret; - } - } - - } - - return null; - - } - - - public void GetStates() { - - - // Get a pointer to the desktop accessible object. - long desktopPointer = LibAtSpi.atspi_get_desktop(0); - assertEquals(true, desktopPointer > 0); - System.out.println("Desktop pointer: " + desktopPointer); - - - // Test the child count - get a reference for the current state. - // For some reason this throws a lot of console messages of: - // g_object_unref: assertion 'G_IS_OBJECT (object)' failed - int childCount = LibAtSpi.atspi_accessible_get_child_count(desktopPointer, 0); - - - // Test the children as AtSpiAccessible instances. - List childrenExt = AtSpiAccessible.getAccessibleChildren(desktopPointer); - assertEquals(childCount, childrenExt.size()); - - - // Test the get state set method. - long stateSetPtr = LibAtSpi.atspi_accessible_get_state_set(desktopPointer); - assertEquals(true, stateSetPtr > 0); - - - } - - -} diff --git a/linux/src/org/testar/monkey/example/tests/LibGdiPlusTests.java b/linux/src/org/testar/monkey/example/tests/LibGdiPlusTests.java deleted file mode 100644 index 19ff037e0..000000000 --- a/linux/src/org/testar/monkey/example/tests/LibGdiPlusTests.java +++ /dev/null @@ -1,77 +0,0 @@ -/*************************************************************************************************** -* -* Copyright (c) 2017 Open Universiteit - www.ou.nl -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, -* this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the copyright holder nor the names of its -* contributors may be used to endorse or promote products derived from -* this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -* POSSIBILITY OF SUCH DAMAGE. -*******************************************************************************************************/ - -package org.testar.monkey.example.tests; - -import org.bridj.Pointer; -import org.testar.monkey.alayer.linux.gdiplus.LibGdiPlus; -import org.junit.jupiter.api.Test; - - -import static org.junit.jupiter.api.Assertions.*; - - - -/** - * Unit tests for working with Mono's implementation of the GDI+ API. - */ -public class LibGdiPlusTests { - - - - @Test - public void MonitorMethods() { - - - // ULong_Ptrs are defined as uint32. - Pointer token = Pointer.allocateInt(); - Pointer input = Pointer.allocateInt(); - Pointer output = Pointer.allocateLong(); - - - // Get a handle to the primary monitor. - long pmHnd = LibGdiPlus.GdiplusStartup(token, input, output); - System.out.println("Token: " + token.getInt()); - System.out.println("Input: " + input.getInt()); - System.out.println("Output: " + output.getLong()); - assertTrue(pmHnd == 0); - - if (pmHnd == 0) { - - } - - - - - - } - - - -} diff --git a/linux/src/org/testar/monkey/example/tests/LibGtk3Tests.java b/linux/src/org/testar/monkey/example/tests/LibGtk3Tests.java deleted file mode 100644 index 1b761e8d2..000000000 --- a/linux/src/org/testar/monkey/example/tests/LibGtk3Tests.java +++ /dev/null @@ -1,177 +0,0 @@ -/*************************************************************************************************** -* -* Copyright (c) 2017 Open Universiteit - www.ou.nl -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, -* this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the copyright holder nor the names of its -* contributors may be used to endorse or promote products derived from -* this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -* POSSIBILITY OF SUCH DAMAGE. -*******************************************************************************************************/ - -package org.testar.monkey.example.tests; - - -import org.bridj.Pointer; -import org.testar.monkey.alayer.linux.util.BridJHelper; -import org.testar.monkey.alayer.linux.LinuxProcess; -import org.testar.monkey.alayer.linux.glib.GList; -import org.testar.monkey.alayer.linux.gtk3.LibGtk3; -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; - - -/** - * Unit tests for working with the GTK+ 3 API. - */ -public class LibGtk3Tests { - - - private final String DefaultDisplay = ":0"; - private static final String ApplicationPath_GEdit = "/usr/bin/gedit"; - - - @Test - public void openDisplay() { - - - long displayPointer = LibGtk3.gdk_display_get_default(); - assertEquals(0, displayPointer); - - - displayPointer = LibGtk3.gdk_display_open(BridJHelper.convertToPointer(DefaultDisplay)); - assertEquals(true, displayPointer > 0); - - - Pointer displayName = LibGtk3.gdk_display_get_name(displayPointer); - assertEquals(":0", displayName.getCString()); - - - boolean isClosed = LibGtk3.gdk_display_is_closed(displayPointer); - assertEquals(false, isClosed); - - - LibGtk3.gdk_display_close(displayPointer); - //System.out.println("Display closed!"); - - - - long displayMngrPtr = LibGtk3.gdk_display_manager_get(); - assertEquals(true, displayMngrPtr > 0); - - - // This function will only retrieve the default display if it has already been opened. - long defaultDisplayPointer = LibGtk3.gdk_display_manager_get_default_display(displayMngrPtr); - assertEquals(0, defaultDisplayPointer); - - - //Pointer defaultDisplayName = LibGtk3.gdk_display_get_name(defaultDisplayPointer); - //assertEquals(":0", defaultDisplayName.getCString()); - - - } - - - @Test - public void screensAndMonitors() { - - - long displayPointer = LibGtk3.gdk_display_open(BridJHelper.convertToPointer(DefaultDisplay)); - assertEquals(true, displayPointer > 0); - - - long screenPointer = LibGtk3.gdk_display_get_default_screen(displayPointer); - assertEquals(true, screenPointer > 0); - - - // This code should not be used when using GTK 3.22 or higher - it's deprecated. - int width = LibGtk3.gdk_screen_get_width(screenPointer); - int height = LibGtk3.gdk_screen_get_height(screenPointer); - assertEquals(1920, width); - assertEquals(975, height); - - - - // We're using 3.18.9.1 - this code should be used when using 3.22 or higher. -// int monitorCount = LibGtk3.gdk_display_get_n_monitors(displayPointer); -// assertEquals(1, monitorCount); -// -// -// long monitorPtr = LibGtk3.gdk_display_get_monitor(displayPointer, monitorCount - 1); -// assertEquals(true, monitorPtr > 0); - - - LibGtk3.gdk_display_close(displayPointer); - - - } - - - @Test - public void screensAndWindows() { - - - long displayPointer = LibGtk3.gdk_display_open(BridJHelper.convertToPointer(DefaultDisplay)); - assertEquals(true, displayPointer > 0); - - - long screenPointer = LibGtk3.gdk_display_get_default_screen(displayPointer); - assertEquals(true, screenPointer > 0); - - - // Get the root window. - long rootWindowPtr = LibGtk3.gdk_screen_get_root_window(screenPointer); - assertEquals(true, rootWindowPtr > 0); - - - // Launch a new application. - LinuxProcess gedit = LinuxProcess.fromExecutable(ApplicationPath_GEdit); - - - // Short pause to give the application time to start. - try { - Thread.sleep(200); - } catch (InterruptedException e) { - e.printStackTrace(); - } - - - // Get a pointer to a GList structure containing pointers to GDKWindows. - long listPtr = LibGtk3.gdk_screen_get_toplevel_windows(screenPointer); - assertEquals(true, listPtr > 0); - - - GList topLevelWindowPtrList = GList.CreateInstance(listPtr, Long.class); - assertNotNull(topLevelWindowPtrList); - assert topLevelWindowPtrList != null; - assertEquals(true, topLevelWindowPtrList.length() > 0); - - - // Close the display. - LibGtk3.gdk_display_close(displayPointer); - - - } - - -} diff --git a/linux/src/org/testar/monkey/example/tests/LibWnckTests.java b/linux/src/org/testar/monkey/example/tests/LibWnckTests.java deleted file mode 100644 index 90760b0e5..000000000 --- a/linux/src/org/testar/monkey/example/tests/LibWnckTests.java +++ /dev/null @@ -1,234 +0,0 @@ -/*************************************************************************************************** -* -* Copyright (c) 2017 Open Universiteit - www.ou.nl -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, -* this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the copyright holder nor the names of its -* contributors may be used to endorse or promote products derived from -* this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -* POSSIBILITY OF SUCH DAMAGE. -*******************************************************************************************************/ - -package org.testar.monkey.example.tests; - - -import org.testar.monkey.alayer.linux.LinuxProcess; -import org.testar.monkey.alayer.linux.glib.GList; -import org.testar.monkey.alayer.linux.gtk3.LibGtk3; -import org.testar.monkey.alayer.linux.libwnck.LibWnck; -import org.testar.monkey.alayer.linux.libwnck.WnckWindow; -import org.junit.jupiter.api.Test; - -import java.util.ArrayList; - -import static org.junit.jupiter.api.Assertions.*; - - -/** - * Unit tests for working with the LibWnck API. - */ -public class LibWnckTests { - - - private static final String ApplicationPath_Galculator = "/usr/bin/galculator"; - - // Id should be retrieved manually after running a galculator instance. - private static final long GalculatorXid = 35651587; - - - @Test - public void screenMethods() { - - - LibGtk3.gdk_init(0, 0); - - - long screenPointer = LibWnck.wnck_screen_get_default(); - assertTrue(screenPointer > 0); - - - int width = LibWnck.wnck_screen_get_width(screenPointer); - int heigth = LibWnck.wnck_screen_get_height(screenPointer); - assertEquals(1920, width); - assertEquals(975, heigth); - - - // Before accessing anything about windows, the screen needs to be filled with information - force_update needed. - LibWnck.wnck_screen_force_update(screenPointer); - - - long windowListPtr = LibWnck.wnck_screen_get_windows(screenPointer); - assertTrue(windowListPtr > 0); - - - GList windows = GList.CreateInstance(windowListPtr, Long.class); - ArrayList windowsList = new ArrayList<>(); - - - assert windows != null; - for (Long w : windows.elements()) { - - WnckWindow win = WnckWindow.CreateInstance(w); - - if (win != null && win.windowPtr() > 1000000) { - win.fillDebug(); - windowsList.add(win); - } - - } - - - - long activeWindowPtr = LibWnck.wnck_screen_get_active_window(screenPointer); - System.out.println("Active window ptr: " + activeWindowPtr); - assertTrue(activeWindowPtr > 0); - - - WnckWindow activeWindow = WnckWindow.CreateInstance(activeWindowPtr); - assertNotNull(activeWindow); - assert activeWindow != null; - System.out.println("Active window name: " + activeWindow.name()); - activeWindow.fillDebug(); - - - // Launch an application - which will become the active window. - LinuxProcess calc = LinuxProcess.fromExecutable(ApplicationPath_Galculator); - - - // Short pause to give the application time to start. - try { - Thread.sleep(200); - } catch (InterruptedException e) { - e.printStackTrace(); - } - - - // Flush the gtk event loop. - while (LibGtk3.gtk_events_pending()) { - LibGtk3.gtk_main_iteration(); - } - - - GList windows2 = GList.CreateInstance(windowListPtr, Long.class); - ArrayList windowsList2 = new ArrayList<>(); - - - assert windows2 != null; - for (Long w : windows2.elements()) { - - WnckWindow win = WnckWindow.CreateInstance(w); - - if (win != null && win.windowPtr() > 1000000) { - win.fillDebug(); - windowsList2.add(win); - } - - } - - - // Check if the window pointer changed. - long activeWindowPtr2 = LibWnck.wnck_screen_get_active_window(screenPointer); - System.out.println("Active window ptr 2: " + activeWindowPtr2); - assertTrue(activeWindowPtr2 > 0); - assertNotEquals(activeWindowPtr, activeWindowPtr2); - - - WnckWindow activeWindow2 = WnckWindow.CreateInstance(activeWindowPtr); - assertNotNull(activeWindow2); - assert activeWindow2 != null; - System.out.println("Active window name 2: " + activeWindow2.name()); - activeWindow2.fillDebug(); - assertNotEquals(activeWindow.name(), activeWindow2.name()); - - - // Flush the gtk event loop. - while (LibGtk3.gtk_events_pending()) { - LibGtk3.gtk_main_iteration(); - } - - - // Check if the window pointer changed. - long activeWindowPtr3 = LibWnck.wnck_screen_get_active_window(screenPointer); - System.out.println("Active window ptr 3: " + activeWindowPtr2); - assertTrue(activeWindowPtr3 > 0); - assertNotEquals(activeWindowPtr2, activeWindowPtr3); - - - WnckWindow activeWindow3 = WnckWindow.CreateInstance(activeWindowPtr); - assertNotNull(activeWindow3); - assert activeWindow3 != null; - System.out.println("Active window name 3: " + activeWindow3.name()); - activeWindow3.fillDebug(); - assertNotEquals(activeWindow2.name(), activeWindow3.name()); - - - calc.stop(); - - - } - - - @Test - public void windowActive() { - - - LibGtk3.gdk_init(0, 0); - - - long screenPointer = LibWnck.wnck_screen_get_default(); - assertTrue(screenPointer > 0); - - - // Before accessing anything about windows, the screen needs to be filled with information - force_update needed. - LibWnck.wnck_screen_force_update(screenPointer); - - - long windowPointer = LibWnck.wnck_window_get(GalculatorXid); - assertTrue(windowPointer > 0); - - - WnckWindow galculator = WnckWindow.CreateInstance(windowPointer); - assertNotNull(galculator); - assert galculator != null; - galculator.fillDebug(); - - - boolean isActive = LibWnck.wnck_window_is_active(windowPointer); - assertFalse(isActive); - - - LibWnck.wnck_window_activate(windowPointer, (int)(System.currentTimeMillis() / 1000)); - - - // Flush the gtk event loop. - while (LibGtk3.gtk_events_pending()) { - LibGtk3.gtk_main_iteration(); - } - - isActive = LibWnck.wnck_window_is_active(windowPointer); - assertTrue(isActive); - - - - } - - -} diff --git a/linux/src/org/testar/monkey/example/tests/LibX11Tests.java b/linux/src/org/testar/monkey/example/tests/LibX11Tests.java deleted file mode 100644 index aa74d9289..000000000 --- a/linux/src/org/testar/monkey/example/tests/LibX11Tests.java +++ /dev/null @@ -1,138 +0,0 @@ -/*************************************************************************************************** -* -* Copyright (c) 2017 Open Universiteit - www.ou.nl -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, -* this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the copyright holder nor the names of its -* contributors may be used to endorse or promote products derived from -* this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -* POSSIBILITY OF SUCH DAMAGE. -*******************************************************************************************************/ - -package org.testar.monkey.example.tests; - - -import org.bridj.Pointer; -import org.testar.monkey.alayer.linux.util.BridJHelper; -import org.testar.monkey.alayer.linux.xlib.LibX11; -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.*; - - -/** - * Unit tests for working with the LibX11 API. - */ -public class LibX11Tests { - - - /** - * Tests XLib functions. - */ - @Test - public void testLibX11() { - - - // First, get a pointer to a Display structure for the current machine; when null is used the - // environment variable DISPLAY is used which translates to ':0'. - long displayPointer = LibX11.XOpenDisplay(null); - - - if (displayPointer == 0) { - System.out.println("Cannot open the display!"); - return; - } - assertEquals(true, displayPointer > 0); - - - // Get the string used to retrieve the display. - Pointer displayStringPtr = LibX11.XDisplayString(displayPointer); - System.out.println("Display opened with string: '" + displayStringPtr.getCString() + "'."); - assertEquals(":0", displayStringPtr.getCString()); - - - // Get the default screen number of the current display. - int defaultScreenNumber = LibX11.XDefaultScreen(displayPointer); - System.out.println("Default display screen number: '" + defaultScreenNumber + "'."); - assertEquals(0, defaultScreenNumber); - - - // Get the dimensions of the display. - int displayHeighth = LibX11.XDisplayHeight(displayPointer, defaultScreenNumber); - int displayWidth = LibX11.XDisplayWidth(displayPointer, defaultScreenNumber); - System.out.println("Display dimensions: '" + displayWidth + "x" + displayHeighth + "'."); - assertEquals(1920, displayWidth); - - - // Get the number of screens connected to the display adapter. - int screenCount = LibX11.XScreenCount(displayPointer); - System.out.println("Number of screens connected to the display adapter: '" + screenCount + "'."); - assertEquals(1, screenCount); - - - // Now get the RootWindow. - // TODO: get/create a Window object or check if the returned pointer can be used somehow. - long rootWindow = LibX11.XRootWindow(displayPointer, defaultScreenNumber); - - - if (rootWindow == 0) { - - } - - - // Find the Atom specifying the PID. - long netWmPid = LibX11.XInternAtom(displayPointer, BridJHelper.convertToPointer("_NET_WM_PID"), true); - System.out.println("_NET_WM_PID: '" + netWmPid + "'."); - assertEquals(true, netWmPid > 0); - - - // !!! Does not work!!! -// long XA_CARDINAL = 6; -// long type = 0; -// int format = 0; -// long nItems = 0; -// long bytesAfter = 0; -// long propPID = 0; -// -// -// int returnVal = LibX11.XGetWindowProperty(displayPointer, rootWindow, netWmPid, 0, 1, false, XA_CARDINAL, -// type, format, nItems, bytesAfter, propPID); - - - // TODO: Find the Window for a given PID. - - - - // TODO: Bring the Window to the foreground - most likely an XSendEvent is necessary, raising doesn't give focus or unhide from mimimize. - // Bring the window given its WindowId to the foreground. - //LibX11.XRaiseWindow(displayPointer, 65011747); // 67108874 - - - - // Close connection to the opened display. - LibX11.XCloseDisplay(displayPointer); - System.out.println("Display closed!"); - - - } - - -} diff --git a/linux/src/org/testar/monkey/example/tests/LinuxProcessTests.java b/linux/src/org/testar/monkey/example/tests/LinuxProcessTests.java deleted file mode 100644 index c1d0bdd6c..000000000 --- a/linux/src/org/testar/monkey/example/tests/LinuxProcessTests.java +++ /dev/null @@ -1,216 +0,0 @@ -/*************************************************************************************************** -* -* Copyright (c) 2017 Open Universiteit - www.ou.nl -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, -* this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the copyright holder nor the names of its -* contributors may be used to endorse or promote products derived from -* this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -* POSSIBILITY OF SUCH DAMAGE. -*******************************************************************************************************/ - -package org.testar.monkey.example.tests; - - -import org.junit.jupiter.api.Test; -import static org.junit.jupiter.api.Assertions.*; - - -import org.testar.monkey.alayer.SUT; -import org.testar.monkey.alayer.linux.LinuxProcess; - - -import java.util.List; - - - -/** - * Unit tests for working with Linux processes. - */ -public class LinuxProcessTests { - - - private static final String ApplicationPath_GEdit = "/usr/bin/gedit"; - private static final String ApplicationPath_Galculator = "/usr/bin/galculator"; - - - @Test - public void GetRunningProcesses() { - - - // Get a list of processes. - List processes = LinuxProcess.fromAll(); - - - // Make sure it succeeded. - assertNotNull(processes, "Could not retrieve any processes!"); - - - - } - - - @Test - public void LaunchProcess() { - - - // Launch an application. - LinuxProcess lp = LinuxProcess.fromExecutable(ApplicationPath_GEdit); - - - // Make sure it is running. - assertNotNull(lp,"Failed to launch the requested application."); - assertEquals(true, lp.isRunning()); - - - // Create a LinuxProcess instance and check if it also returns running. - LinuxProcess gedit = LinuxProcess.fromPid(lp.get_pid()); - assertEquals(true, gedit.isRunning()); - - - try { - Thread.sleep(200); - } catch (InterruptedException e) { - e.printStackTrace(); - } - - // Stop the process and check isRunning again for both LinuxProcess instances. - gedit.stop(); - - - try { - Thread.sleep(200); - } catch (InterruptedException e) { - e.printStackTrace(); - } - - assertEquals(false, lp.isRunning()); - assertEquals(false, gedit.isRunning()); - - - } - - - @Test - public void ProcessStats() { - - - // Launch an application. - LinuxProcess lp = LinuxProcess.fromExecutable(ApplicationPath_GEdit); - - - // Make sure it is running. - assertNotNull(lp,"Failed to launch the requested application."); - assertEquals(true, lp.isRunning()); - - - // Check the usage stats. - long mem = LinuxProcess.getMemUsage(lp); - double cpu = LinuxProcess.getCpuUsage(lp); - - - // If nothing failed then memory will not be zero but cpu will be zero or very small. - assertEquals(true, mem > 0); - assertEquals(true, cpu >= 0.0 && cpu < 5.0, "CPU: " + cpu); - - - // Check the process name. - String processName = lp.getProcessName(); - assertEquals(ApplicationPath_GEdit, processName); - - - try { - Thread.sleep(200); - } catch (InterruptedException e) { - e.printStackTrace(); - } - - - // Stop the process and check isRunning again for both LinuxProcess instances. - lp.stop(); - - - try { - Thread.sleep(200); - } catch (InterruptedException e) { - e.printStackTrace(); - } - - - assertEquals(false, lp.isRunning()); - - - } - - - @Test - public void ActivateProcess() { - - - LinuxProcess galc = LinuxProcess.fromExecutable(ApplicationPath_Galculator); - assertNotNull(galc); - - - // Short pause to give the applications time to start. - try { - Thread.sleep(500); - } catch (InterruptedException e) { - e.printStackTrace(); - } - - - - boolean isActive = galc.isActive(); - assertTrue(isActive); - - - LinuxProcess gedit = LinuxProcess.fromExecutable(ApplicationPath_GEdit); - assertNotNull(gedit); - - - // Short pause to give the applications time to start. - try { - Thread.sleep(500); - } catch (InterruptedException e) { - e.printStackTrace(); - } - - - isActive = galc.isActive(); - assertFalse(isActive); - - - boolean activation = galc.activate(); - assertTrue(activation); - - - isActive = galc.isActive(); - assertTrue(isActive); - - - galc.stop(); - gedit.stop(); - - - } - - -} diff --git a/linux/src/org/testar/monkey/example/tests/TreeWalkerTests.java b/linux/src/org/testar/monkey/example/tests/TreeWalkerTests.java deleted file mode 100644 index 9ae844909..000000000 --- a/linux/src/org/testar/monkey/example/tests/TreeWalkerTests.java +++ /dev/null @@ -1,372 +0,0 @@ -/*************************************************************************************************** -* -* Copyright (c) 2017 Open Universiteit - www.ou.nl -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, -* this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the copyright holder nor the names of its -* contributors may be used to endorse or promote products derived from -* this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -* POSSIBILITY OF SUCH DAMAGE. -*******************************************************************************************************/ - -package org.testar.monkey.example.tests; - - -import org.testar.monkey.alayer.linux.LinuxProcess; -import org.testar.monkey.alayer.linux.atspi.AtSpiAccessible; -import org.testar.monkey.alayer.linux.atspi.TreeWalker; -import org.testar.monkey.alayer.linux.atspi.enums.AtSpiRoles; -import org.testar.monkey.alayer.linux.util.xdotools; -import org.junit.jupiter.api.Test; - -import java.util.ArrayList; -import java.util.List; - -import static org.junit.jupiter.api.Assertions.*; - - -/** - * Unit Test to test the TreeWalker functionality. - */ -public class TreeWalkerTests { - - - private static final String ApplicationPath_GEdit = "/usr/bin/gedit"; - private static final String ApplicationPath_Galculator = "/usr/bin/galculator"; - - - @Test - public void ApplicationMethods() { - - - - // Launch two instances of the calculator. - LinuxProcess calc1 = LinuxProcess.fromExecutable(ApplicationPath_Galculator); - LinuxProcess calc2 = LinuxProcess.fromExecutable(ApplicationPath_Galculator); - - - // Short pause to give the applications time to start. - try { - Thread.sleep(200); - } catch (InterruptedException e) { - e.printStackTrace(); - } - - - List applicationNodes = TreeWalker.getApplicationNodes(determineApplicationName(ApplicationPath_Galculator), false); - assertEquals(true, applicationNodes.size() > 1); - - - System.out.println("Galculator apps running: " + applicationNodes.size()); - - - // Give user time to setup windows. - try { - Thread.sleep(5000); - } catch (InterruptedException e) { - e.printStackTrace(); - } - - - // Lets see if we can find calculator number 2. - // Determine if active application is one of the calculators. - AtSpiAccessible activeCalculator = TreeWalker.getActiveApplicationNode(applicationNodes); - int pid; - - - if (activeCalculator == null) { - System.out.println("No calculator is the active application."); - } else { - - - // Retrieve name and PID through xdotools. - pid = xdotools.getPIDFromActiveWindow(); - assertTrue(pid > 0); - - String name = xdotools.getNameFromActiveWindow(); - - - System.out.println("Active application is: '" + name + "' with PID: " + pid); - - - // Check if the PID matches calculator 2. - if (pid == calc2.get_pid()) { - System.out.println("Calculator 2 already active - done!"); - calc1.stop(); - calc2.stop(); - return; - } else if (pid == calc1.get_pid()) { - System.out.println("Calculator 1 is active - continuing search for calculator 2..."); - } - - - } - - - boolean foundCalc = false; - - - // Did not find calculator 2 yet from active applications. - // Activate each application through AT-SPI and find the PID for each active application through xprop. - for (AtSpiAccessible application : applicationNodes) { - - - // Activate application. - if (TreeWalker.activateApplication(application)) { - - // Short pause to give the application time to activate. - try { - Thread.sleep(200); - } catch (InterruptedException e) { - e.printStackTrace(); - } - - - // Retrieve name and PID through xdotools. - pid = xdotools.getPIDFromActiveWindow(); - assertTrue(pid > 0); - - String name = xdotools.getNameFromActiveWindow(); - - - System.out.println("Active application is: '" + name + "' with PID: " + pid); - - - // Check if the PID matches calculator 2. - if (pid == calc2.get_pid()) { - System.out.println("Found calculator 2!"); - foundCalc = true; - break; - } else if (pid == calc1.get_pid()) { - System.out.println("Found calculator 1 - continuing search for calculator 2..."); - } - - - } else { - System.out.println("Cannot activate the application!"); - } - - - } - - - if (!foundCalc) { - System.out.println("Could not find calculator 2!"); - } - - - calc1.stop(); - calc2.stop(); - - - if (!foundCalc) { - fail("Could not find calculator 2!"); - } - - - } - - - @Test - public void ApplicationStats() { - - - // Launch two instances of the calculator. - LinuxProcess calc = LinuxProcess.fromExecutable(ApplicationPath_Galculator); - - - // Short pause to give the applications time to start. - try { - Thread.sleep(200); - } catch (InterruptedException e) { - e.printStackTrace(); - } - - - List applicationNodes = TreeWalker.getApplicationNodes(determineApplicationName(ApplicationPath_Galculator), false); - assertEquals(true, applicationNodes.size() > 0); - - - for (AtSpiAccessible a : applicationNodes) { - a.retrieveAccessibleInfoTree(); - } - - } - - - @Test - public void MultipleWindows() { - - - // Launch two instances of the calculator. - LinuxProcess ged1 = LinuxProcess.fromExecutable(ApplicationPath_GEdit); - LinuxProcess ged2 = LinuxProcess.fromExecutable(ApplicationPath_GEdit); - - - // Short pause to give the applications time to start - and user to mess around. - try { - Thread.sleep(5000); - } catch (InterruptedException e) { - e.printStackTrace(); - } - - - List applicationNodes = TreeWalker.getApplicationNodes("soffice", false); - //List applicationNodes = TreeWalker.getApplicationNodes(determineApplicationName(ApplicationPath_GEdit), false); - assertEquals(true, applicationNodes.size() > 0); - - - for (AtSpiAccessible a : applicationNodes) { - a.retrieveAccessibleInfoTree(); - } - - - List scrollbars = TreeWalker.findNodesWithRole(applicationNodes.get(0), AtSpiRoles.ScrollBar); - - for (AtSpiAccessible s : scrollbars) { - s.retrieveAccessibleInfoTree(); - } - - - List relationNodes = getRelationNodes(applicationNodes.get(0)); - - - for (AtSpiAccessible s : relationNodes) { - s.retrieveAccessibleInfoTree(); - } - - - // Stop the applications. - ged1.stop(); - ged2.stop(); - - - } - - - @Test - public void Modality() { - - - // Launch LibreOffice manually before running this so you can create a modal dialog or not. - List applicationNodes = TreeWalker.getApplicationNodes("soffice", true); - assertTrue(applicationNodes.size() > 0); - - - boolean hasModals = TreeWalker.hasApplicationModalDialogs(applicationNodes.get(0)); - System.out.println("Has modals: " + hasModals); - - - List nonModals = TreeWalker.getNonModalApplicationChildNodes(applicationNodes.get(0)); - - - for (AtSpiAccessible a : nonModals) { - a.retrieveAccessibleInfo(); - } - System.out.println("NonModals: " + nonModals.size()); - - - } - - - @Test - public void Modality2() { - - - - // Short pause to give the applications time to start. - try { - Thread.sleep(5000); - } catch (InterruptedException e) { - e.printStackTrace(); - } - - - // Launch LibreOffice manually before running this so you can create a modal dialog or not. - List applicationNodes = TreeWalker.getApplicationNodes("eclipse", true); - assertTrue(applicationNodes.size() > 0); - - - boolean hasModals = TreeWalker.hasApplicationModalDialogs(applicationNodes.get(0)); - System.out.println("Has modals: " + hasModals); - - - List nonModals = TreeWalker.getNonModalApplicationChildNodes(applicationNodes.get(0)); - - - for (AtSpiAccessible a : nonModals) { - a.retrieveAccessibleInfo(); - } - System.out.println("NonModals: " + nonModals.size()); - - - List modals = TreeWalker.getModalApplicationChildNodes(applicationNodes.get(0)); - - - for (AtSpiAccessible a : modals) { - a.retrieveAccessibleInfo(); - } - System.out.println("Modals: " + modals.size()); - - - } - - - - /** - * Retrieves the name of an application from its file path. - * @param path The file path of the executable that creates the application. - * @return The name of the application. - */ - private String determineApplicationName(String path) { - - return path.substring(path.lastIndexOf("/") + 1); - - } - - - /** - * Creates a list of nodes that own relations. - * @param node The node to start looking from. - * @return A List of nodes that have relations. - */ - private List getRelationNodes(AtSpiAccessible node) { - - - ArrayList relationNodes = new ArrayList<>(); - - - if (node.relations().size() > 0) { - relationNodes.add(node); - } - - for (AtSpiAccessible a : node.children()) { - for (AtSpiAccessible as : getRelationNodes(a)) { - relationNodes.add(as); - } - } - - return relationNodes; - - } - - -} diff --git a/settings.gradle b/settings.gradle index 6244f67c6..69b0a4857 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,2 +1,2 @@ -include 'core', 'windows', 'testar', 'linux', 'webdriver', 'android', 'ios', 'statemodel' +include 'core', 'windows', 'testar', 'webdriver', 'android', 'ios', 'statemodel' diff --git a/testar/build.gradle b/testar/build.gradle index 64453ef44..1c6e75e34 100644 --- a/testar/build.gradle +++ b/testar/build.gradle @@ -90,7 +90,6 @@ dependencies { implementation project(':statemodel') implementation project(':webdriver') implementation project(':windows') - implementation project(':linux') implementation project(':ios') implementation project(':android') implementation files('./lib/jsyntaxpane-1.1.5.jar') diff --git a/testar/resources/settings/desktop_widget_recognition/Protocol_desktop_widget_recognition.java b/testar/resources/settings/desktop_widget_recognition/Protocol_desktop_widget_recognition.java index 6581051a7..5c981d8c8 100644 --- a/testar/resources/settings/desktop_widget_recognition/Protocol_desktop_widget_recognition.java +++ b/testar/resources/settings/desktop_widget_recognition/Protocol_desktop_widget_recognition.java @@ -1,7 +1,7 @@ /*************************************************************************************************** * - * Copyright (c) 2013 - 2024 Universitat Politecnica de Valencia - www.upv.es - * Copyright (c) 2018 - 2024 Open Universiteit - www.ou.nl + * Copyright (c) 2013 - 2026 Universitat Politecnica de Valencia - www.upv.es + * Copyright (c) 2018 - 2026 Open Universiteit - www.ou.nl * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -34,7 +34,6 @@ import org.sikuli.script.FindFailed; import org.sikuli.script.Screen; import org.testar.DerivedActions; -import org.testar.ProtocolUtil; import org.testar.SutVisualization; import org.testar.monkey.ConfigTags; import org.testar.monkey.Util; @@ -49,6 +48,7 @@ import org.testar.protocols.DesktopProtocol; import org.testar.settings.Settings; import org.testar.simplestategraph.GuiStateGraphWithVisitedActions; +import org.testar.util.ScreenshotUtil; import java.awt.image.BufferedImage; import java.io.File; @@ -179,7 +179,7 @@ protected boolean executeAction(SUT system, State state, Action action){ // You can increase the ActionDuration settings time for visual debugging Util.clear(cv); cv.end(); - String widgetScreenshotPath = ProtocolUtil.getActionshot(state, action); + String widgetScreenshotPath = ScreenshotUtil.getActionshot(state, action); System.out.println("widgetScreenshotPath " + widgetScreenshotPath); if (detector == Detector.EYE) { diff --git a/testar/src/org/testar/SutVisualization.java b/testar/src/org/testar/SutVisualization.java index d15b7b384..1c1c16161 100644 --- a/testar/src/org/testar/SutVisualization.java +++ b/testar/src/org/testar/SutVisualization.java @@ -1,7 +1,7 @@ /*************************************************************************************************** * - * Copyright (c) 2018 - 2025 Universitat Politecnica de Valencia - www.upv.es - * Copyright (c) 2018 - 2025 Open Universiteit - www.ou.nl + * Copyright (c) 2018 - 2026 Universitat Politecnica de Valencia - www.upv.es + * Copyright (c) 2018 - 2026 Open Universiteit - www.ou.nl * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -31,12 +31,12 @@ package org.testar; import org.testar.settings.dialog.tagsvisualization.TagFilter; +import org.testar.util.VisualizationUtil; import org.testar.monkey.Util; import org.testar.monkey.alayer.*; import org.testar.monkey.alayer.devices.Mouse; import org.testar.monkey.ConfigTags; import org.testar.settings.Settings; -import java.util.Iterator; import java.util.Set; import static org.testar.monkey.alayer.Tags.Role; import static org.testar.monkey.alayer.Tags.Visualizer; @@ -65,13 +65,12 @@ public static void visualizeFilteredActions(Canvas canvas, State state, Set Toggle widget-tree hierarchy display - if (markParentWidget){ - String cursorWidgetID = cursorWidget.get(Tags.ConcreteID); - boolean print = !cursorWidgetID.equals(lastPrintParentsOf); - if (print){ - lastPrintParentsOf = cursorWidgetID; - System.out.println("Parents of: " + cursorWidget.get(Tags.Title)); - } - int lvls = ProtocolUtil.markParents(canvas,cursorWidget,ProtocolUtil.ancestorsMarkingColors.keySet().iterator(),0,print); - if (lvls > 0){ - Shape legendShape = ProtocolUtil.repositionShape(canvas,Rect.from(cursor.x(), cursor.y(), 110, lvls*25)); - canvas.rect(Pen.PEN_WHITE_ALPHA, legendShape.x(), legendShape.y(), legendShape.width(), legendShape.height()); - canvas.rect(Pen.PEN_BLACK, legendShape.x(), legendShape.y(), legendShape.width(), legendShape.height()); - int shadow = 2; - String l; - Iterator it = ProtocolUtil.ancestorsMarkingColors.keySet().iterator(); - for (int i=0; i actions) { if (promptGenerator.attachImage()) { ByteArrayOutputStream screenshotBytes = new ByteArrayOutputStream(); - AWTCanvas screenshot; - if(NativeLinker.getPLATFORM_OS().contains(OperatingSystems.WEBDRIVER)){ - screenshot = WdProtocolUtil.getStateshotBinary(state); - } else if (NativeLinker.getPLATFORM_OS().contains(OperatingSystems.ANDROID)) { - screenshot = AndroidProtocolUtil.getStateshotBinary(state); - } else if (NativeLinker.getPLATFORM_OS().contains(OperatingSystems.IOS)) { - screenshot = IOSProtocolUtil.getStateshotBinary(state); - } - else screenshot = ProtocolUtil.getStateshotBinary(state); + AWTCanvas screenshot = ScreenshotProviderFactory.current().getStateshotBinary(state); try { screenshot.saveAsPng(screenshotBytes); diff --git a/testar/src/org/testar/monkey/AbstractProtocol.java b/testar/src/org/testar/monkey/AbstractProtocol.java index b091174c2..b87f98ebe 100644 --- a/testar/src/org/testar/monkey/AbstractProtocol.java +++ b/testar/src/org/testar/monkey/AbstractProtocol.java @@ -42,6 +42,7 @@ import java.util.List; import java.util.Set; +import java.util.function.Consumer; /** * This is the abstract flow of TESTAR (generate mode): @@ -65,7 +66,7 @@ * - CloseTestSession (after finishing the last sequence) * */ -public abstract class AbstractProtocol implements UnProc { +public abstract class AbstractProtocol implements Consumer { protected Settings settings; protected Settings settings(){ return settings; } diff --git a/testar/src/org/testar/monkey/DefaultProtocol.java b/testar/src/org/testar/monkey/DefaultProtocol.java index 9c0b3fe16..414299122 100644 --- a/testar/src/org/testar/monkey/DefaultProtocol.java +++ b/testar/src/org/testar/monkey/DefaultProtocol.java @@ -38,15 +38,12 @@ import org.testar.monkey.alayer.actions.ActivateSystem; import org.testar.monkey.alayer.actions.AnnotatingActionCompiler; import org.testar.monkey.alayer.actions.KillProcess; -import org.testar.monkey.alayer.android.AndroidProtocolUtil; import org.testar.monkey.alayer.devices.AWTMouse; import org.testar.monkey.alayer.devices.DummyMouse; import org.testar.monkey.alayer.devices.KBKeys; import org.testar.monkey.alayer.devices.Mouse; import org.testar.monkey.alayer.exceptions.*; -import org.testar.monkey.alayer.ios.IOSProtocolUtil; import org.testar.monkey.alayer.visualizers.ShapeVisualizer; -import org.testar.monkey.alayer.webdriver.WdProtocolUtil; import org.testar.monkey.alayer.windows.UIARoles; import org.testar.monkey.alayer.windows.WinApiException; import org.testar.oracles.Oracle; @@ -54,16 +51,17 @@ import org.testar.oracles.log.LogOracle; import org.testar.oracles.log.ProcessListenerOracle; import org.testar.plugin.NativeLinker; -import org.testar.plugin.OperatingSystems; import org.testar.reporting.DummyReportManager; import org.testar.reporting.ReportManager; import org.testar.reporting.Reporting; +import org.testar.screenshot.ScreenshotProviderFactory; import org.testar.serialisation.LogSerialiser; import org.testar.serialisation.ScreenshotSerialiser; import org.testar.serialisation.TestSerialiser; import org.testar.settings.Settings; import org.testar.statemodel.StateModelManager; import org.testar.statemodel.StateModelManagerFactory; +import org.testar.util.IndexUtil; import java.awt.Desktop; import java.awt.GraphicsEnvironment; @@ -215,7 +213,8 @@ protected final double timeElapsed() { * * @param settings */ - public final void run(final Settings settings) { + @Override + public final void accept(final Settings settings) { //Associate start settings of the first TESTAR dialog this.settings = settings; @@ -788,7 +787,7 @@ protected State getState(SUT system) throws StateBuildException { State state = builder.apply(system); buildStateIdentifiers(state); - state = ProtocolUtil.calculateZIndices(state); + state = IndexUtil.calculateZIndices(state); setStateForClickFilterLayerProtocol(state); @@ -826,19 +825,7 @@ protected State getState(SUT system) throws StateBuildException { private void setStateScreenshot(State state) { // If the environment is not headless, take a screenshot if (!GraphicsEnvironment.isHeadless()) { - AWTCanvas screenshot = null; - if(NativeLinker.getPLATFORM_OS().contains(OperatingSystems.WEBDRIVER)){ - screenshot = WdProtocolUtil.getStateshotBinary(state); - } - else if(NativeLinker.getPLATFORM_OS().contains(OperatingSystems.ANDROID)) { - screenshot = AndroidProtocolUtil.getStateshotBinary(state); - } - else if(NativeLinker.getPLATFORM_OS().contains(OperatingSystems.IOS)) { - screenshot = IOSProtocolUtil.getStateshotBinary(state); - } - else { - screenshot = ProtocolUtil.getStateshotBinary(state); - } + AWTCanvas screenshot = ScreenshotProviderFactory.current().getStateshotBinary(state); if(screenshot != null) { String screenshotPath = ScreenshotSerialiser.saveStateshot(state.get(Tags.ConcreteID, "NoConcreteIdAvailable"), screenshot); @@ -1056,13 +1043,7 @@ protected boolean executeAction(SUT system, State state, Action action){ // adding the action that is going to be executed into report: reportManager.addSelectedAction(state, action); - if(NativeLinker.getPLATFORM_OS().contains(OperatingSystems.WEBDRIVER)){ - WdProtocolUtil.getActionshot(state,action); - }else if(NativeLinker.getPLATFORM_OS().contains(OperatingSystems.ANDROID)){ - AndroidProtocolUtil.getActionshot(state,action); - }else{ - ProtocolUtil.getActionshot(state,action); - } + ScreenshotProviderFactory.current().getActionshot(state, action); double waitTime = settings.get(ConfigTags.TimeToWaitAfterAction); @@ -1095,11 +1076,7 @@ protected boolean replayAction(SUT system, State state, Action action, double ac reportManager.addSelectedAction(state, action); // Get an action screenshot based on the NativeLinker platform - if(NativeLinker.getPLATFORM_OS().contains(OperatingSystems.WEBDRIVER)) { - WdProtocolUtil.getActionshot(state,action); - } else { - ProtocolUtil.getActionshot(state,action); - } + ScreenshotProviderFactory.current().getActionshot(state, action); try{ double halfWait = actionWaitTime == 0 ? 0.01 : actionWaitTime / 2.0; // seconds diff --git a/testar/src/org/testar/monkey/Main.java b/testar/src/org/testar/monkey/Main.java index 438c7e9f5..7a9438729 100644 --- a/testar/src/org/testar/monkey/Main.java +++ b/testar/src/org/testar/monkey/Main.java @@ -58,13 +58,14 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.util.*; +import java.util.function.Consumer; import static org.testar.monkey.ConfigTags.*; import static org.testar.monkey.Util.compileProtocol; public class Main { - public static final String TESTAR_VERSION = "v2.8.5 (17-Mar-2026)"; + public static final String TESTAR_VERSION = "v2.8.6 (24-Mar-2026)"; //public static final String TESTAR_DIR_PROPERTY = "DIRNAME"; //Use the OS environment to obtain TESTAR directory public static final String SETTINGS_FILE = "test.settings"; @@ -377,13 +378,13 @@ private static void startTestar(Settings settings) { "' with class path '" + Util.toString(cp) + "'\n", LogSerialiser.LogLevel.Debug); @SuppressWarnings("unchecked") - UnProc protocol = (UnProc) loader.loadClass(protocolClass).getConstructor().newInstance(); + Consumer protocol = (Consumer) loader.loadClass(protocolClass).getConstructor().newInstance(); LogSerialiser.log("TESTAR protocol loaded!\n", LogSerialiser.LogLevel.Debug); LogSerialiser.log("Starting TESTAR protocol ...\n", LogSerialiser.LogLevel.Debug); //Run TESTAR protocol with the selected settings - protocol.run(settings); + protocol.accept(settings); } catch (InstantiationException e) { e.printStackTrace(); diff --git a/testar/src/org/testar/monkey/RuntimeControlsProtocol.java b/testar/src/org/testar/monkey/RuntimeControlsProtocol.java index 879e05951..763db19ef 100644 --- a/testar/src/org/testar/monkey/RuntimeControlsProtocol.java +++ b/testar/src/org/testar/monkey/RuntimeControlsProtocol.java @@ -1,7 +1,7 @@ /*************************************************************************************************** * - * Copyright (c) 2018 - 2023 Universitat Politecnica de Valencia - www.upv.es - * Copyright (c) 2018 - 2023 Open Universiteit - www.ou.nl + * Copyright (c) 2018 - 2026 Universitat Politecnica de Valencia - www.upv.es + * Copyright (c) 2018 - 2026 Open Universiteit - www.ou.nl * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -43,7 +43,6 @@ public abstract class RuntimeControlsProtocol extends AbstractProtocol implement protected double delay = Double.MIN_VALUE; protected Object[] userEvent = null; - protected boolean markParentWidget = false; protected boolean visualizationOn = false; public enum Modes{ @@ -126,11 +125,6 @@ else if(key == KBKeys.VK_UP && pressed.contains(KBKeys.VK_SHIFT)){ else if (key == KBKeys.VK_0 && pressed.contains(KBKeys.VK_SHIFT)) { System.setProperty("DEBUG_WINDOWS_PROCESS_NAMES","true"); } - - // SHIFT + ALT --> Toggle widget-tree hierarchy display - if (pressed.contains(KBKeys.VK_ALT) && pressed.contains(KBKeys.VK_SHIFT)) { - markParentWidget = !markParentWidget; - } } } diff --git a/testar/src/org/testar/monkey/SpyMode.java b/testar/src/org/testar/monkey/SpyMode.java index 19e34295d..72149d36e 100644 --- a/testar/src/org/testar/monkey/SpyMode.java +++ b/testar/src/org/testar/monkey/SpyMode.java @@ -1,7 +1,7 @@ /*************************************************************************************************** * - * Copyright (c) 2022 - 2025 Open Universiteit - www.ou.nl - * Copyright (c) 2022 - 2025 Universitat Politecnica de Valencia - www.upv.es + * Copyright (c) 2022 - 2026 Open Universiteit - www.ou.nl + * Copyright (c) 2022 - 2026 Universitat Politecnica de Valencia - www.upv.es * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -39,10 +39,10 @@ import org.testar.monkey.alayer.Action; import org.testar.monkey.alayer.SUT; import org.testar.monkey.alayer.State; -import org.testar.monkey.alayer.android.AndroidProtocolUtil; import org.testar.monkey.alayer.android.spy_visualization.MobileVisualizationAndroid; -import org.testar.monkey.alayer.ios.IOSProtocolUtil; +import org.testar.monkey.alayer.android.util.AndroidScreenshotUtil; import org.testar.monkey.alayer.ios.spy_visualization.MobileVisualizationIOS; +import org.testar.monkey.alayer.ios.util.IOSScreenshotUtil; import org.testar.plugin.NativeLinker; import org.testar.plugin.OperatingSystems; @@ -137,13 +137,13 @@ private MobileVisualizationAndroid setupAndroidVisualization(DefaultProtocol pro System.out.println("SPY MODE, CREATING JAVA JFRAME WINDOW Android"); State state = protocol.getState(system); Function> deriveActionsFunction = s -> protocol.deriveActions(system, s); - return new MobileVisualizationAndroid(AndroidProtocolUtil.getStateshotSpyMode(state), state, deriveActionsFunction); + return new MobileVisualizationAndroid(AndroidScreenshotUtil.getStateshotSpyMode(state), state, deriveActionsFunction); } private MobileVisualizationIOS setupIOSVisualization(DefaultProtocol protocol, SUT system) { System.out.println("SPY MODE, CREATING JAVA JFRAME WINDOW iOS"); State state = protocol.getState(system); - return new MobileVisualizationIOS(IOSProtocolUtil.getStateshotSpyMode(state), state); + return new MobileVisualizationIOS(IOSScreenshotUtil.getStateshotSpyMode(state), state); } private void updateAndroidVisualization(DefaultProtocol protocol, MobileVisualizationAndroid visualization, SUT system, State state) { @@ -168,7 +168,6 @@ private void updateDefaultVisualization(DefaultProtocol protocol, SUT system, St //in Spy-mode, always visualize the widget info under the mouse cursor: SutVisualization.visualizeState( protocol.visualizationOn, - protocol.markParentWidget, protocol.mouse, protocol.lastPrintParentsOf, protocol.cv, diff --git a/testar/src/org/testar/monkey/SutConnectorWindowTitle.java b/testar/src/org/testar/monkey/SutConnectorWindowTitle.java index 716914aa7..d97fdb711 100644 --- a/testar/src/org/testar/monkey/SutConnectorWindowTitle.java +++ b/testar/src/org/testar/monkey/SutConnectorWindowTitle.java @@ -1,7 +1,7 @@ /*************************************************************************************************** * - * Copyright (c) 2020 Open Universiteit - www.ou.nl - * Copyright (c) 2020 Universitat Politecnica de Valencia - www.upv.es + * Copyright (c) 2020 - 2026 Open Universiteit - www.ou.nl + * Copyright (c) 2020 - 2026 Universitat Politecnica de Valencia - www.upv.es * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -31,12 +31,15 @@ package org.testar.monkey; import org.testar.CodingManager; -import org.testar.ProtocolUtil; import org.testar.monkey.alayer.*; import org.testar.monkey.alayer.exceptions.StateBuildException; import org.testar.monkey.alayer.exceptions.SystemStartException; import org.testar.plugin.NativeLinker; +import org.testar.screenshot.ScreenshotProviderFactory; +import org.testar.serialisation.ScreenshotSerialiser; +import org.testar.util.IndexUtil; +import java.awt.GraphicsEnvironment; import java.util.List; public class SutConnectorWindowTitle implements SutConnector { @@ -55,21 +58,19 @@ public SutConnectorWindowTitle(String windowTitle, double maxEngangeTime, StateB @Override public SUT startOrConnectSut() throws SystemStartException { - List suts = null; - State state; Role role; String title; long now = System.currentTimeMillis(); do{ Util.pauseMs(100); - suts = NativeLinker.getNativeProcesses(); + List suts = NativeLinker.getNativeProcesses(); if (suts != null){ for (SUT theSUT : suts){ - state = getStateByWindowTitle(theSUT); + State state = getStateByWindowTitle(theSUT); // If the system is in the foreground or if the option to force to the foreground is enabled if (state.get(Tags.Foreground) || forceToForeground){ for (Widget w : state){ - role = w.get(Tags.Role, null); + Role role = w.get(Tags.Role, null); if (role != null && Role.isOneOf(role, NativeLinker.getNativeRole_Window())){ - title = w.get(Tags.Title, null); + String title = w.get(Tags.Title, null); if (title != null && title.contains(windowTitle)){ System.out.println("SUT with Window Title -" + windowTitle + "- DETECTED!"); return theSUT; @@ -90,12 +91,16 @@ protected State getStateByWindowTitle(SUT system) throws StateBuildException { CodingManager.buildIDs(state); Shape viewPort = state.get(Tags.Shape, null); - if(viewPort != null){ - state.set(Tags.ScreenshotPath, ProtocolUtil.getStateshot(state)); - //Don't include WdProtocolUtil option because TESTAR doesn't connect to webdrivers through the windows title + if(!GraphicsEnvironment.isHeadless() && viewPort != null){ + AWTCanvas screenshot = ScreenshotProviderFactory.current().getStateshotBinary(state); + + if(screenshot != null) { + String screenshotPath = ScreenshotSerialiser.saveStateshot(state.get(Tags.ConcreteID, "NoConcreteIdAvailable"), screenshot); + state.set(Tags.ScreenshotPath, screenshotPath); + } } - state = ProtocolUtil.calculateZIndices(state); + state = IndexUtil.calculateZIndices(state); return state; } diff --git a/testar/src/org/testar/oracles/llm/LlmOracle.java b/testar/src/org/testar/oracles/llm/LlmOracle.java index b9b17b50e..09684c3ef 100644 --- a/testar/src/org/testar/oracles/llm/LlmOracle.java +++ b/testar/src/org/testar/oracles/llm/LlmOracle.java @@ -47,7 +47,6 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.testar.llm.prompt.IPromptOracleGenerator; -import org.testar.ProtocolUtil; import org.testar.llm.LlmConversation; import org.testar.llm.LlmFactory; import org.testar.llm.LlmResponse; @@ -58,12 +57,8 @@ import org.testar.monkey.alayer.AWTCanvas; import org.testar.monkey.alayer.State; import org.testar.monkey.alayer.Verdict; -import org.testar.monkey.alayer.android.AndroidProtocolUtil; -import org.testar.monkey.alayer.ios.IOSProtocolUtil; -import org.testar.monkey.alayer.webdriver.WdProtocolUtil; import org.testar.oracles.Oracle; -import org.testar.plugin.NativeLinker; -import org.testar.plugin.OperatingSystems; +import org.testar.screenshot.ScreenshotProviderFactory; import org.testar.settings.Settings; public class LlmOracle implements Oracle { @@ -141,15 +136,7 @@ private Verdict getVerdictWithLlm(State state) { if (promptGenerator.attachImage()) { ByteArrayOutputStream screenshotBytes = new ByteArrayOutputStream(); - AWTCanvas screenshot; - if(NativeLinker.getPLATFORM_OS().contains(OperatingSystems.WEBDRIVER)){ - screenshot = WdProtocolUtil.getStateshotBinary(state); - } else if (NativeLinker.getPLATFORM_OS().contains(OperatingSystems.ANDROID)) { - screenshot = AndroidProtocolUtil.getStateshotBinary(state); - } else if (NativeLinker.getPLATFORM_OS().contains(OperatingSystems.IOS)) { - screenshot = IOSProtocolUtil.getStateshotBinary(state); - } - else screenshot = ProtocolUtil.getStateshotBinary(state); + AWTCanvas screenshot = ScreenshotProviderFactory.current().getStateshotBinary(state); try { screenshot.saveAsPng(screenshotBytes); diff --git a/testar/src/org/testar/plugin/NativeLinker.java b/testar/src/org/testar/plugin/NativeLinker.java index 8fde4fe0a..5652fe2ec 100644 --- a/testar/src/org/testar/plugin/NativeLinker.java +++ b/testar/src/org/testar/plugin/NativeLinker.java @@ -1,7 +1,7 @@ /*************************************************************************************************** * - * Copyright (c) 2013 - 2025 Universitat Politecnica de Valencia - www.upv.es - * Copyright (c) 2018 - 2025 Open Universiteit - www.ou.nl + * Copyright (c) 2013 - 2026 Universitat Politecnica de Valencia - www.upv.es + * Copyright (c) 2018 - 2026 Open Universiteit - www.ou.nl * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -33,7 +33,6 @@ import org.testar.monkey.alayer.*; import org.testar.monkey.alayer.devices.ProcessHandle; import org.testar.monkey.alayer.exceptions.NoSuchTagException; -import org.testar.monkey.alayer.linux.*; import org.testar.monkey.alayer.webdriver.WdCanvas; import org.testar.monkey.alayer.webdriver.WdDriver; import org.testar.monkey.alayer.webdriver.WdStateBuilder; @@ -52,7 +51,6 @@ import java.util.*; -import static org.testar.monkey.alayer.linux.AtSpiRolesWrapper.*; import static org.testar.monkey.alayer.windows.UIARoles.*; /** @@ -146,10 +144,8 @@ else if (PLATFORM_OS.contains(OperatingSystems.WINDOWS_10)) { System.out.println("TESTAR detected OS: " + osName + " and this is not yet full supported. If the detected OS is wrong, please contact the TESTAR team at info@testar.org."); return new UIAStateBuilder(timeToFreeze, accessBridgeEnabled, SUTProcesses); } - } else if (PLATFORM_OS.contains(OperatingSystems.UNIX)) { - return new AtSpiStateBuilder(timeToFreeze); } - + System.out.println("TESTAR detected OS: " + osName + " and this is not yet supported. If the detected OS is wrong, please contact the TESTAR team at info@testar.org. Exiting with Exception."); throw new UnsupportedPlatformException(); } @@ -171,12 +167,8 @@ public static Canvas getNativeCanvas(Pen pen){ } if (PLATFORM_OS.contains(OperatingSystems.WINDOWS)) { return GDIScreenCanvas.fromPrimaryMonitor(pen); - //return JavaScreenCanvas.fromPrimaryMonitor(pen); - } else if (PLATFORM_OS.contains(OperatingSystems.UNIX)) { - // TODO: spy mode on linux still needs to be implemented - The Canvas is also being used by Test mode. - return new GdkScreenCanvas(); - //return JavaScreenCanvas.fromPrimaryMonitor(pen); } + throw new UnsupportedPlatformException(); } @@ -213,9 +205,7 @@ else if (PLATFORM_OS.contains(OperatingSystems.WINDOWS_10)) { return WinProcess.fromExecutable(executableCommand, ProcessListenerEnabled, SUTProcesses); } } - else if (PLATFORM_OS.contains(OperatingSystems.UNIX)) { - return LinuxProcess.fromExecutable(executableCommand); - } + throw new UnsupportedPlatformException(); } @@ -235,24 +225,21 @@ else if (PLATFORM_OS.contains(OperatingSystems.IOS)) { } else if (PLATFORM_OS.contains(OperatingSystems.WINDOWS)) return WinProcess.fromAll(); - else if (PLATFORM_OS.contains(OperatingSystems.UNIX)) - return LinuxProcess.fromAll(); + throw new UnsupportedPlatformException(); } public static SUT getNativeProcess(String processName){ if (PLATFORM_OS.contains(OperatingSystems.WINDOWS)) return WinProcess.fromProcName(processName); - //else if (PLATFORM_OS.contains(OperatingSystems.UNIX)) - // TODO + throw new UnsupportedPlatformException(); } public static ProcessHandle getNativeProcessHandle(long processPID){ if (PLATFORM_OS.contains(OperatingSystems.WINDOWS)) return new WinProcHandle(processPID); - else if (PLATFORM_OS.contains(OperatingSystems.UNIX)) - return new LinuxProcessHandle(processPID); + throw new UnsupportedPlatformException(); } @@ -273,8 +260,7 @@ public static int getMemUsage(SUT nativeSUT){ } if (PLATFORM_OS.contains(OperatingSystems.WINDOWS)) return (int)(WinProcess.getMemUsage((WinProcess)nativeSUT) / 1024); // byte -> KB - else if (PLATFORM_OS.contains(OperatingSystems.UNIX)) - return (int)(LinuxProcess.getMemUsage((LinuxProcess)nativeSUT) / 1024); + throw new UnsupportedPlatformException(); } @@ -302,12 +288,8 @@ public static long[] getCPUsage(SUT nativeSUT){ lastCPUquery = now; long[] cpums = WinProcess.getCPUsage((WinProcess)nativeSUT); return new long[]{ cpums[0], cpums[1], cpuFrame }; - } else if (PLATFORM_OS.contains(OperatingSystems.UNIX)) { - // TODO: this probably needs to change somehow... - return new long[] { (long)(LinuxProcess.getCpuUsage((LinuxProcess)nativeSUT)), - (long)(LinuxProcess.getCpuUsage((LinuxProcess)nativeSUT)), - (long)(LinuxProcess.getCpuUsage((LinuxProcess)nativeSUT))}; } + throw new UnsupportedPlatformException(); } @@ -323,8 +305,7 @@ public static Collection getNativeRoles(){ } if (PLATFORM_OS.contains(OperatingSystems.WINDOWS)) return UIARoles.rolesSet(); - // else if (PLATFORM_OS.contains(OperatingSystems.UNIX)) - // TODO + throw new UnsupportedPlatformException(); } @@ -355,8 +336,7 @@ public static Collection getNativeRoles(String... roleNames){ public static Role getNativeRole_Window(){ if (PLATFORM_OS.contains(OperatingSystems.WINDOWS)) return UIARoles.UIAWindow; - else if (PLATFORM_OS.contains(OperatingSystems.UNIX)) - return AtSpiRolesWrapper.AtSpiWindow; + throw new UnsupportedPlatformException(); } @@ -371,8 +351,7 @@ public static Set> getNativeTags(){ return AndroidTags.tagSet(); if (PLATFORM_OS.contains(OperatingSystems.WINDOWS)) return UIATags.tagSet(); - else if (PLATFORM_OS.contains(OperatingSystems.UNIX)) - return AtSpiTags.tagSet(); + throw new UnsupportedPlatformException(); } @@ -422,11 +401,8 @@ public static Role[] getNativeClickableRoles(){ UIATabItem, UIAHyperlink, UIADataItem, UIATree, UIATreeItem, UIASlider, UIASpinner, UIAScrollBar, UIASplitButton, UIACustomControl}; // be careful on custom control (we do not know what they are) - } else if (PLATFORM_OS.contains(OperatingSystems.UNIX)) { - return new Role[]{AtSpiCheckBox, AtSpiCheckMenuItem, AtSpiComboBox, AtSpiMenuItem, - AtSpiListItem, AtSpiSpinButton, AtSpiToggleButton, AtSpiTreeItem, AtSpiListBox, - AtSpiPushButton, AtSpiLink, AtSpiScrollBar}; } + throw new UnsupportedPlatformException(); } @@ -441,9 +417,7 @@ public static Role[] getNativeTypeableRoles(){ return AndroidRoles.nativeTypeableRoles(); if (PLATFORM_OS.contains(OperatingSystems.WINDOWS)) return new Role[]{UIADocument, UIAEdit, UIAText}; - else if (PLATFORM_OS.contains(OperatingSystems.UNIX)) - return new Role[]{AtSpiPasswordText, AtSpiText, AtSpiDocumentText, AtSpiDocumentWeb, - AtSpiDocumentEmail}; + throw new UnsupportedPlatformException(); } @@ -457,8 +431,7 @@ public static boolean isNativeTypeable(Widget w){ return false; if (PLATFORM_OS.contains(OperatingSystems.WINDOWS)) return w.get(UIATags.UIAIsKeyboardFocusable); - else if (PLATFORM_OS.contains(OperatingSystems.UNIX)) - return w.get(AtSpiTags.AtSpiIsFocusable); + throw new UnsupportedPlatformException(); } } diff --git a/testar/src/org/testar/screenshot/ScreenshotProviderFactory.java b/testar/src/org/testar/screenshot/ScreenshotProviderFactory.java new file mode 100644 index 000000000..ad93a22c2 --- /dev/null +++ b/testar/src/org/testar/screenshot/ScreenshotProviderFactory.java @@ -0,0 +1,128 @@ +/*************************************************************************************************** + * + * Copyright (c) 2026 Open Universiteit - www.ou.nl + * Copyright (c) 2026 Universitat Politecnica de Valencia - www.upv.es + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *******************************************************************************************************/ + +package org.testar.screenshot; + +import org.testar.monkey.alayer.Action; + +import java.util.Objects; +import java.util.Set; + +import org.testar.monkey.alayer.AWTCanvas; +import org.testar.monkey.alayer.State; +import org.testar.monkey.alayer.android.util.AndroidScreenshotUtil; +import org.testar.monkey.alayer.ios.util.IOSScreenshotUtil; +import org.testar.monkey.alayer.webdriver.util.WdScreenshotUtil; +import org.testar.plugin.NativeLinker; +import org.testar.plugin.OperatingSystems; +import org.testar.util.ScreenshotUtil; + +public final class ScreenshotProviderFactory { + + private static final ScreenshotProvider DEFAULT_PROVIDER = new ScreenshotProvider() { + @Override + public AWTCanvas getStateshotBinary(State state) { + Objects.requireNonNull(state, "State cannot be null"); + return ScreenshotUtil.getStateshotBinary(state); + } + + @Override + public String getActionshot(State state, Action action) { + Objects.requireNonNull(state, "State cannot be null"); + Objects.requireNonNull(action, "Action cannot be null"); + return ScreenshotUtil.getActionshot(state, action); + } + }; + + private static final ScreenshotProvider WEBDRIVER_PROVIDER = new ScreenshotProvider() { + @Override + public AWTCanvas getStateshotBinary(State state) { + Objects.requireNonNull(state, "State cannot be null"); + return WdScreenshotUtil.getStateshotBinary(state); + } + + @Override + public String getActionshot(State state, Action action) { + Objects.requireNonNull(state, "State cannot be null"); + Objects.requireNonNull(action, "Action cannot be null"); + return WdScreenshotUtil.getActionshot(state, action); + } + }; + + private static final ScreenshotProvider ANDROID_PROVIDER = new ScreenshotProvider() { + @Override + public AWTCanvas getStateshotBinary(State state) { + Objects.requireNonNull(state, "State cannot be null"); + return AndroidScreenshotUtil.getStateshotBinary(state); + } + + @Override + public String getActionshot(State state, Action action) { + Objects.requireNonNull(state, "State cannot be null"); + Objects.requireNonNull(action, "Action cannot be null"); + return AndroidScreenshotUtil.getActionshot(state, action); + } + }; + + private static final ScreenshotProvider IOS_PROVIDER = new ScreenshotProvider() { + @Override + public AWTCanvas getStateshotBinary(State state) { + Objects.requireNonNull(state, "State cannot be null"); + return IOSScreenshotUtil.getStateshotBinary(state); + } + + @Override + public String getActionshot(State state, Action action) { + Objects.requireNonNull(state, "State cannot be null"); + Objects.requireNonNull(action, "Action cannot be null"); + return IOSScreenshotUtil.getActionshot(state, action); + } + }; + + private ScreenshotProviderFactory() { + } + + public static ScreenshotProvider current() { + Set platform = NativeLinker.getPLATFORM_OS(); + if (platform == null) { + return DEFAULT_PROVIDER; + } + if (platform.contains(OperatingSystems.WEBDRIVER)) { + return WEBDRIVER_PROVIDER; + } + if (platform.contains(OperatingSystems.ANDROID)) { + return ANDROID_PROVIDER; + } + if (platform.contains(OperatingSystems.IOS)) { + return IOS_PROVIDER; + } + return DEFAULT_PROVIDER; + } +} diff --git a/testar/test/org/testar/monkey/screenshot/ScreenshotProviderFactoryTest.java b/testar/test/org/testar/monkey/screenshot/ScreenshotProviderFactoryTest.java new file mode 100644 index 000000000..b0cea5169 --- /dev/null +++ b/testar/test/org/testar/monkey/screenshot/ScreenshotProviderFactoryTest.java @@ -0,0 +1,218 @@ +package org.testar.monkey.screenshot; + +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; +import static org.mockito.Mockito.mock; + +import java.util.Arrays; +import java.util.EnumSet; +import java.util.List; +import java.util.Set; + +import org.junit.Test; +import org.mockito.MockedStatic; +import org.mockito.Mockito; +import org.testar.monkey.alayer.AWTCanvas; +import org.testar.monkey.alayer.Action; +import org.testar.monkey.alayer.State; +import org.testar.monkey.alayer.android.util.AndroidScreenshotUtil; +import org.testar.monkey.alayer.ios.util.IOSScreenshotUtil; +import org.testar.monkey.alayer.webdriver.util.WdScreenshotUtil; +import org.testar.plugin.NativeLinker; +import org.testar.plugin.OperatingSystems; +import org.testar.screenshot.ScreenshotProvider; +import org.testar.screenshot.ScreenshotProviderFactory; +import org.testar.util.ScreenshotUtil; + +public class ScreenshotProviderFactoryTest { + + @Test + public void webdriver_provider() { + State state = mock(State.class); + Action action = mock(Action.class); + AWTCanvas expected_stateshot = mock(AWTCanvas.class); + String expected_actionshot = "webdriver-action-path"; + + try (MockedStatic nativeLinker = Mockito.mockStatic(NativeLinker.class); + MockedStatic wd = Mockito.mockStatic(WdScreenshotUtil.class)) { + + nativeLinker.when(NativeLinker::getPLATFORM_OS).thenReturn(EnumSet.of(OperatingSystems.WEBDRIVER)); + wd.when(() -> WdScreenshotUtil.getStateshotBinary(state)).thenReturn(expected_stateshot); + wd.when(() -> WdScreenshotUtil.getActionshot(state, action)).thenReturn(expected_actionshot); + + ScreenshotProvider provider = ScreenshotProviderFactory.current(); + assertSame(expected_stateshot, provider.getStateshotBinary(state)); + assertSame(expected_actionshot, provider.getActionshot(state, action)); + } + } + + @Test + public void android_provider() { + State state = mock(State.class); + Action action = mock(Action.class); + AWTCanvas expected_stateshot = mock(AWTCanvas.class); + String expected_actionshot = "android-action-path"; + + try (MockedStatic nativeLinker = Mockito.mockStatic(NativeLinker.class); + MockedStatic android = Mockito.mockStatic(AndroidScreenshotUtil.class)) { + + nativeLinker.when(NativeLinker::getPLATFORM_OS).thenReturn(EnumSet.of(OperatingSystems.ANDROID)); + android.when(() -> AndroidScreenshotUtil.getStateshotBinary(state)).thenReturn(expected_stateshot); + android.when(() -> AndroidScreenshotUtil.getActionshot(state, action)).thenReturn(expected_actionshot); + + ScreenshotProvider provider = ScreenshotProviderFactory.current(); + assertSame(expected_stateshot, provider.getStateshotBinary(state)); + assertSame(expected_actionshot, provider.getActionshot(state, action)); + } + } + + @Test + public void ios_provider() { + State state = mock(State.class); + Action action = mock(Action.class); + AWTCanvas expected_stateshot = mock(AWTCanvas.class); + String expected_actionshot = "ios-action-path"; + + try (MockedStatic nativeLinker = Mockito.mockStatic(NativeLinker.class); + MockedStatic ios = Mockito.mockStatic(IOSScreenshotUtil.class)) { + + nativeLinker.when(NativeLinker::getPLATFORM_OS).thenReturn(EnumSet.of(OperatingSystems.IOS)); + ios.when(() -> IOSScreenshotUtil.getStateshotBinary(state)).thenReturn(expected_stateshot); + ios.when(() -> IOSScreenshotUtil.getActionshot(state, action)).thenReturn(expected_actionshot); + + ScreenshotProvider provider = ScreenshotProviderFactory.current(); + assertSame(expected_stateshot, provider.getStateshotBinary(state)); + assertSame(expected_actionshot, provider.getActionshot(state, action)); + } + } + + @Test + public void default_provider() { + State state = mock(State.class); + Action action = mock(Action.class); + AWTCanvas expected_stateshot = mock(AWTCanvas.class); + String expected_actionshot = "default-action-path"; + + try (MockedStatic nativeLinker = Mockito.mockStatic(NativeLinker.class); + MockedStatic defaultUtil = Mockito.mockStatic(ScreenshotUtil.class)) { + + nativeLinker.when(NativeLinker::getPLATFORM_OS).thenReturn(EnumSet.of(OperatingSystems.WINDOWS)); + defaultUtil.when(() -> ScreenshotUtil.getStateshotBinary(state)).thenReturn(expected_stateshot); + defaultUtil.when(() -> ScreenshotUtil.getActionshot(state, action)).thenReturn(expected_actionshot); + + ScreenshotProvider provider = ScreenshotProviderFactory.current(); + assertSame(expected_stateshot, provider.getStateshotBinary(state)); + assertSame(expected_actionshot, provider.getActionshot(state, action)); + } + } + + @Test + public void prioritization_provider() { + State state = mock(State.class); + AWTCanvas expected = mock(AWTCanvas.class); + + try (MockedStatic nativeLinker = Mockito.mockStatic(NativeLinker.class); + MockedStatic wd = Mockito.mockStatic(WdScreenshotUtil.class)) { + + nativeLinker.when(NativeLinker::getPLATFORM_OS).thenReturn(EnumSet.of(OperatingSystems.WEBDRIVER, OperatingSystems.ANDROID)); + wd.when(() -> WdScreenshotUtil.getStateshotBinary(state)).thenReturn(expected); + + ScreenshotProvider provider = ScreenshotProviderFactory.current(); + assertSame(expected, provider.getStateshotBinary(state)); + } + } + + @Test + public void default_provider_when_platform_is_null() { + State state = mock(State.class); + Action action = mock(Action.class); + AWTCanvas expected_stateshot = mock(AWTCanvas.class); + String expected_actionshot = "default-action-path"; + + try (MockedStatic nativeLinker = Mockito.mockStatic(NativeLinker.class); + MockedStatic defaultUtil = Mockito.mockStatic(ScreenshotUtil.class)) { + + nativeLinker.when(NativeLinker::getPLATFORM_OS).thenReturn(null); + defaultUtil.when(() -> ScreenshotUtil.getStateshotBinary(state)).thenReturn(expected_stateshot); + defaultUtil.when(() -> ScreenshotUtil.getActionshot(state, action)).thenReturn(expected_actionshot); + + ScreenshotProvider provider = ScreenshotProviderFactory.current(); + assertSame(expected_stateshot, provider.getStateshotBinary(state)); + assertSame(expected_actionshot, provider.getActionshot(state, action)); + } + } + + @Test + public void provider_stateshot_null_state_throws() { + List> platforms = Arrays.asList( + EnumSet.of(OperatingSystems.WINDOWS), + EnumSet.of(OperatingSystems.WEBDRIVER), + EnumSet.of(OperatingSystems.ANDROID), + EnumSet.of(OperatingSystems.IOS) + ); + + for (Set platform : platforms) { + try (MockedStatic nativeLinker = Mockito.mockStatic(NativeLinker.class)) { + nativeLinker.when(NativeLinker::getPLATFORM_OS).thenReturn(platform); + ScreenshotProvider provider = ScreenshotProviderFactory.current(); + try { + provider.getStateshotBinary(null); + fail("Expected NullPointerException for platform " + platform); + } catch (NullPointerException expected) { + assertEquals("State cannot be null", expected.getMessage()); + } + } + } + } + + @Test + public void provider_actionshot_null_state_throws() { + Action action = mock(Action.class); + + List> platforms = Arrays.asList( + EnumSet.of(OperatingSystems.WINDOWS), + EnumSet.of(OperatingSystems.WEBDRIVER), + EnumSet.of(OperatingSystems.ANDROID), + EnumSet.of(OperatingSystems.IOS) + ); + + for (Set platform : platforms) { + try (MockedStatic nativeLinker = Mockito.mockStatic(NativeLinker.class)) { + nativeLinker.when(NativeLinker::getPLATFORM_OS).thenReturn(platform); + ScreenshotProvider provider = ScreenshotProviderFactory.current(); + try { + provider.getActionshot(null, action); + fail("Expected NullPointerException for platform " + platform); + } catch (NullPointerException expected) { + assertEquals("State cannot be null", expected.getMessage()); + } + } + } + } + + @Test + public void provider_actionshot_null_action_throws() { + State state = mock(State.class); + + List> platforms = Arrays.asList( + EnumSet.of(OperatingSystems.WINDOWS), + EnumSet.of(OperatingSystems.WEBDRIVER), + EnumSet.of(OperatingSystems.ANDROID), + EnumSet.of(OperatingSystems.IOS) + ); + + for (Set platform : platforms) { + try (MockedStatic nativeLinker = Mockito.mockStatic(NativeLinker.class)) { + nativeLinker.when(NativeLinker::getPLATFORM_OS).thenReturn(platform); + ScreenshotProvider provider = ScreenshotProviderFactory.current(); + try { + provider.getActionshot(state, null); + fail("Expected NullPointerException for platform " + platform); + } catch (NullPointerException expected) { + assertEquals("Action cannot be null", expected.getMessage()); + } + } + } + } +} diff --git a/webdriver/src/org/testar/monkey/alayer/webdriver/WdProcessActivator.java b/webdriver/src/org/testar/monkey/alayer/webdriver/WdProcessActivator.java index c8baea0c8..0d5263f02 100644 --- a/webdriver/src/org/testar/monkey/alayer/webdriver/WdProcessActivator.java +++ b/webdriver/src/org/testar/monkey/alayer/webdriver/WdProcessActivator.java @@ -1,6 +1,6 @@ /** - * Copyright (c) 2018, 2019 Open Universiteit - www.ou.nl - * Copyright (c) 2019 Universitat Politecnica de Valencia - www.upv.es + * Copyright (c) 2018 - 2026 Open Universiteit - www.ou.nl + * Copyright (c) 2019 - 2026 Universitat Politecnica de Valencia - www.upv.es * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -30,9 +30,7 @@ package org.testar.monkey.alayer.webdriver; -import org.testar.monkey.Proc; - -public final class WdProcessActivator implements Proc { +public final class WdProcessActivator implements Runnable { public void run() { WdDriver.activate(); diff --git a/webdriver/src/org/testar/monkey/alayer/webdriver/WdProtocolUtil.java b/webdriver/src/org/testar/monkey/alayer/webdriver/WdProtocolUtil.java deleted file mode 100644 index 1c1f9d27e..000000000 --- a/webdriver/src/org/testar/monkey/alayer/webdriver/WdProtocolUtil.java +++ /dev/null @@ -1,133 +0,0 @@ -/** - * Copyright (c) 2018 - 2024 Open Universiteit - www.ou.nl - * Copyright (c) 2018 - 2024 Universitat Politecnica de Valencia - www.upv.es - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holder nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - */ - -package org.testar.monkey.alayer.webdriver; - -import org.testar.ProtocolUtil; -import org.testar.monkey.alayer.*; -import org.testar.monkey.alayer.Shape; -import org.testar.monkey.alayer.actions.ActionRoles; -import org.testar.monkey.alayer.actions.WdActionRoles; -import org.testar.monkey.alayer.webdriver.enums.WdTags; -import org.testar.serialisation.ScreenshotSerialiser; - -import java.awt.*; -import java.util.List; - -import static org.testar.monkey.alayer.webdriver.Constants.scrollThick; - - -public class WdProtocolUtil extends ProtocolUtil { - - public static String getStateshot(State state) { - double width = CanvasDimensions.getCanvasWidth() + ( - state.get(WdTags.WebVerticallyScrollable) ? scrollThick : 0); - double height = CanvasDimensions.getCanvasHeight() + ( - state.get(WdTags.WebHorizontallyScrollable) ? scrollThick : 0); - Rect rect = Rect.from(0, 0, width, height); - AWTCanvas screenshot = WdScreenshot.fromScreenshot(rect, state.get(Tags.HWND, (long)0)); - return ScreenshotSerialiser.saveStateshot(state.get(Tags.ConcreteID), screenshot); - } - - public static String getActionshot(State state, Action action) { - if(action.get(Tags.Role, ActionRoles.Action).isA(WdActionRoles.RemoteAction)) { - return getRemoteActionshot(state, action); - } - - List targets = action.get(Tags.Targets, null); - if (targets == null) { - return null; - } - - Rectangle actionArea = new Rectangle(Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MIN_VALUE, Integer.MIN_VALUE); - for (Finder f : targets) { - Widget widget = f.apply(state); - Shape shape = widget.get(Tags.Shape); - Rectangle r = new Rectangle((int) shape.x(), (int) shape.y(), (int) shape.width(), (int) shape.height()); - actionArea = actionArea.union(r); - } - if (actionArea.isEmpty()) { - return null; - } - - // Actionarea is outside viewport - if (actionArea.x < 0 || actionArea.y < 0 || - actionArea.x + actionArea.width > CanvasDimensions.getCanvasWidth() || - actionArea.y + actionArea.height > CanvasDimensions.getCanvasHeight()) { - return null; - } - - Rect rect = Rect.from(actionArea.x, actionArea.y, actionArea.width + 1, actionArea.height + 1); - AWTCanvas scrshot = WdScreenshot.fromScreenshot(rect, state.get(Tags.HWND, (long)0)); - return ScreenshotSerialiser.saveActionshot(state.get(Tags.ConcreteID, "NoConcreteIdAvailable"), action.get(Tags.ConcreteID, "NoConcreteIdAvailable"), scrshot); - } - - private static String getRemoteActionshot(State state, Action action) { - Rectangle actionArea = new Rectangle(Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MIN_VALUE, Integer.MIN_VALUE); - Shape shape = action.get(Tags.OriginWidget).get(Tags.Shape); - Rectangle r = new Rectangle((int) shape.x(), (int) shape.y(), (int) shape.width(), (int) shape.height()); - actionArea = actionArea.union(r); - - if (actionArea.isEmpty()) { - return null; - } - - // Actionarea is outside viewport - if (actionArea.x < 0 || actionArea.y < 0 || - actionArea.x + actionArea.width > CanvasDimensions.getCanvasWidth() || - actionArea.y + actionArea.height > CanvasDimensions.getCanvasHeight()) { - return null; - } - - Rect rect = Rect.from(actionArea.x, actionArea.y, actionArea.width + 1, actionArea.height + 1); - AWTCanvas scrshot = WdScreenshot.fromScreenshot(rect, state.get(Tags.HWND, (long)0)); - return ScreenshotSerialiser.saveActionshot(state.get(Tags.ConcreteID, "NoConcreteIdAvailable"), action.get(Tags.ConcreteID, "NoConcreteIdAvailable"), scrshot); - } - - public static AWTCanvas getStateshotBinary(State state) { - //If these State Tags are not obtained, the State has an error, use full monitor screen - if(state.get(WdTags.WebVerticallyScrollable, null) == null - && state.get(WdTags.WebHorizontallyScrollable, null) == null) { - //Get a screenshot of all the screen, because SUT ended and we can't obtain the size - Rectangle screenRect = new Rectangle(Toolkit.getDefaultToolkit().getScreenSize()); - AWTCanvas scrshot = AWTCanvas.fromScreenshot(Rect.from(screenRect.getX(), screenRect.getY(), - screenRect.getWidth(), screenRect.getHeight()), state.get(Tags.HWND, (long)0), AWTCanvas.StorageFormat.PNG, 1); - return scrshot; - } - - double width = CanvasDimensions.getCanvasWidth() + ( - state.get(WdTags.WebVerticallyScrollable) ? scrollThick : 0); - double height = CanvasDimensions.getCanvasHeight() + ( - state.get(WdTags.WebHorizontallyScrollable) ? scrollThick : 0); - Rect rect = Rect.from(0, 0, width, height); - AWTCanvas screenshot = WdScreenshot.fromScreenshot(rect, state.get(Tags.HWND, (long)0)); - return screenshot; - } -} \ No newline at end of file diff --git a/webdriver/src/org/testar/monkey/alayer/webdriver/util/WdScreenshotUtil.java b/webdriver/src/org/testar/monkey/alayer/webdriver/util/WdScreenshotUtil.java new file mode 100644 index 000000000..768200c0f --- /dev/null +++ b/webdriver/src/org/testar/monkey/alayer/webdriver/util/WdScreenshotUtil.java @@ -0,0 +1,137 @@ +/** + * Copyright (c) 2018 - 2026 Open Universiteit - www.ou.nl + * Copyright (c) 2018 - 2026 Universitat Politecnica de Valencia - www.upv.es + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + +package org.testar.monkey.alayer.webdriver.util; + +import org.testar.monkey.alayer.*; +import org.testar.monkey.alayer.Shape; +import org.testar.monkey.alayer.actions.ActionRoles; +import org.testar.monkey.alayer.actions.WdActionRoles; +import org.testar.monkey.alayer.webdriver.CanvasDimensions; +import org.testar.monkey.alayer.webdriver.WdScreenshot; +import org.testar.monkey.alayer.webdriver.enums.WdTags; +import org.testar.serialisation.ScreenshotSerialiser; + +import java.awt.*; +import java.util.List; +import java.util.Objects; + +import static org.testar.monkey.alayer.webdriver.Constants.scrollThick; + +public class WdScreenshotUtil { + + public static String getActionshot(State state, Action action) { + Objects.requireNonNull(state, "State cannot be null"); + Objects.requireNonNull(action, "Action cannot be null"); + if(action.get(Tags.Role, ActionRoles.Action).isA(WdActionRoles.RemoteAction)) { + return getRemoteActionshot(state, action); + } + + List targets = action.get(Tags.Targets, null); + if (targets == null) { + return ""; + } + + Rectangle actionArea = new Rectangle(Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MIN_VALUE, Integer.MIN_VALUE); + for (Finder f : targets) { + Widget widget = f.apply(state); + Shape shape = widget.get(Tags.Shape, null); + if (shape == null) + continue; + + Rectangle r = new Rectangle((int) shape.x(), (int) shape.y(), (int) shape.width(), (int) shape.height()); + actionArea = actionArea.union(r); + } + + if (actionArea.isEmpty()) { + return ""; + } + + // Actionarea is outside viewport + if (actionArea.x < 0 || actionArea.y < 0 || + actionArea.x + actionArea.width > CanvasDimensions.getCanvasWidth() || + actionArea.y + actionArea.height > CanvasDimensions.getCanvasHeight()) { + return ""; + } + + Rect rect = Rect.from(actionArea.x, actionArea.y, actionArea.width + 1, actionArea.height + 1); + AWTCanvas scrshot = WdScreenshot.fromScreenshot(rect, state.get(Tags.HWND, (long)0)); + return ScreenshotSerialiser.saveActionshot(state.get(Tags.ConcreteID, "NoConcreteIdAvailable"), action.get(Tags.ConcreteID, "NoConcreteIdAvailable"), scrshot); + } + + private static String getRemoteActionshot(State state, Action action) { + Objects.requireNonNull(state, "State cannot be null"); + Objects.requireNonNull(action, "Action cannot be null"); + + if(action.get(Tags.OriginWidget) == null || action.get(Tags.OriginWidget).get(Tags.Shape) == null) { + return ""; + } + + Rectangle actionArea = new Rectangle(Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MIN_VALUE, Integer.MIN_VALUE); + Shape shape = action.get(Tags.OriginWidget).get(Tags.Shape); + Rectangle r = new Rectangle((int) shape.x(), (int) shape.y(), (int) shape.width(), (int) shape.height()); + actionArea = actionArea.union(r); + + if (actionArea.isEmpty()) { + return ""; + } + + // Actionarea is outside viewport + if (actionArea.x < 0 || actionArea.y < 0 || + actionArea.x + actionArea.width > CanvasDimensions.getCanvasWidth() || + actionArea.y + actionArea.height > CanvasDimensions.getCanvasHeight()) { + return ""; + } + + Rect rect = Rect.from(actionArea.x, actionArea.y, actionArea.width + 1, actionArea.height + 1); + AWTCanvas scrshot = WdScreenshot.fromScreenshot(rect, state.get(Tags.HWND, (long)0)); + return ScreenshotSerialiser.saveActionshot(state.get(Tags.ConcreteID, "NoConcreteIdAvailable"), action.get(Tags.ConcreteID, "NoConcreteIdAvailable"), scrshot); + } + + public static AWTCanvas getStateshotBinary(State state) { + Objects.requireNonNull(state, "State cannot be null"); + //If these State Tags are not obtained, the State has an error, use full monitor screen + if(state.get(WdTags.WebVerticallyScrollable, null) == null + && state.get(WdTags.WebHorizontallyScrollable, null) == null) { + //Get a screenshot of all the screen, because SUT ended and we can't obtain the size + Rectangle screenRect = new Rectangle(Toolkit.getDefaultToolkit().getScreenSize()); + AWTCanvas scrshot = AWTCanvas.fromScreenshot(Rect.from(screenRect.getX(), screenRect.getY(), + screenRect.getWidth(), screenRect.getHeight()), state.get(Tags.HWND, (long)0), AWTCanvas.StorageFormat.PNG, 1); + return scrshot; + } + + double width = CanvasDimensions.getCanvasWidth() + (state.get(WdTags.WebVerticallyScrollable, false) ? scrollThick : 0); + double height = CanvasDimensions.getCanvasHeight() + (state.get(WdTags.WebHorizontallyScrollable, false) ? scrollThick : 0); + Rect rect = Rect.from(0, 0, width, height); + AWTCanvas screenshot = WdScreenshot.fromScreenshot(rect, state.get(Tags.HWND, (long)0)); + return screenshot; + } + +} diff --git a/webdriver/test/org/testar/monkey/alayer/webdriver/util/WdScreenshotUtilTest.java b/webdriver/test/org/testar/monkey/alayer/webdriver/util/WdScreenshotUtilTest.java new file mode 100644 index 000000000..b8648f12e --- /dev/null +++ b/webdriver/test/org/testar/monkey/alayer/webdriver/util/WdScreenshotUtilTest.java @@ -0,0 +1,124 @@ +package org.testar.monkey.alayer.webdriver.util; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.util.Collections; +import java.util.List; + +import org.junit.Test; +import org.testar.monkey.alayer.Action; +import org.testar.monkey.alayer.Finder; +import org.testar.monkey.alayer.Rect; +import org.testar.monkey.alayer.Role; +import org.testar.monkey.alayer.State; +import org.testar.monkey.alayer.Tags; +import org.testar.monkey.alayer.Widget; +import org.testar.monkey.alayer.actions.ActionRoles; +import org.testar.monkey.alayer.actions.WdActionRoles; + +public class WdScreenshotUtilTest { + + @Test + public void getStateshotBinary_NullStateThrows() { + try { + WdScreenshotUtil.getStateshotBinary(null); + fail("Expected NullPointerException"); + } catch (NullPointerException expected) { + assertEquals("State cannot be null", expected.getMessage()); + } + } + + @Test + public void getActionshot_NullStateThrows() { + Action action = mock(Action.class); + try { + WdScreenshotUtil.getActionshot(null, action); + fail("Expected NullPointerException"); + } catch (NullPointerException expected) { + assertEquals("State cannot be null", expected.getMessage()); + } + } + + @Test + public void getActionshot_NullActionThrows() { + State state = mock(State.class); + try { + WdScreenshotUtil.getActionshot(state, null); + fail("Expected NullPointerException"); + } catch (NullPointerException expected) { + assertEquals("Action cannot be null", expected.getMessage()); + } + } + + @Test + public void getActionshot_NoTargetsReturnsEmptyString() { + State state = mock(State.class); + Action action = mock(Action.class); + when(action.get(Tags.Role, ActionRoles.Action)).thenReturn((Role) ActionRoles.Action); + when(action.get(Tags.Targets, null)).thenReturn(null); + + String result = WdScreenshotUtil.getActionshot(state, action); + + assertEquals("", result); + } + + @Test + public void getActionshot_EmptyTargetsReturnsEmptyString() { + State state = mock(State.class); + Action action = mock(Action.class); + when(action.get(Tags.Role, ActionRoles.Action)).thenReturn((Role) ActionRoles.Action); + when(action.get(Tags.Targets, null)).thenReturn(Collections.emptyList()); + + String result = WdScreenshotUtil.getActionshot(state, action); + + assertEquals("", result); + } + + @Test + public void getActionshot_RemoteActionWithoutOriginWidgetReturnsEmptyString() { + State state = mock(State.class); + Action action = mock(Action.class); + + when(action.get(Tags.Role, ActionRoles.Action)).thenReturn((Role) WdActionRoles.RemoteAction); + when(action.get(Tags.OriginWidget)).thenReturn(null); + + String result = WdScreenshotUtil.getActionshot(state, action); + + assertEquals("", result); + } + + @Test + public void getActionshot_RemoteActionWithOutOfViewportShapeReturnsEmptyString() { + State state = mock(State.class); + Action action = mock(Action.class); + Widget origin = mock(Widget.class); + + when(action.get(Tags.Role, ActionRoles.Action)).thenReturn((Role) WdActionRoles.RemoteAction); + when(action.get(Tags.OriginWidget)).thenReturn(origin); + when(origin.get(Tags.Shape)).thenReturn(Rect.from(-10, -10, 5, 5)); + + String result = WdScreenshotUtil.getActionshot(state, action); + + assertEquals("", result); + } + + @Test + public void getActionshot_TargetShapeOutsideViewportReturnsEmptyString() { + State state = mock(State.class); + Action action = mock(Action.class); + Finder finder = mock(Finder.class); + Widget widget = mock(Widget.class); + + when(action.get(Tags.Role, ActionRoles.Action)).thenReturn((Role) ActionRoles.Action); + when(action.get(Tags.Targets, null)).thenReturn(List.of(finder)); + when(finder.apply(state)).thenReturn(widget); + when(widget.get(Tags.Shape)).thenReturn(Rect.from(-10, -10, 5, 5)); + + String result = WdScreenshotUtil.getActionshot(state, action); + + assertEquals("", result); + } +} diff --git a/windows/src/org/testar/monkey/alayer/windows/WinProcessActivator.java b/windows/src/org/testar/monkey/alayer/windows/WinProcessActivator.java index ba824636d..bcbf0112b 100644 --- a/windows/src/org/testar/monkey/alayer/windows/WinProcessActivator.java +++ b/windows/src/org/testar/monkey/alayer/windows/WinProcessActivator.java @@ -1,6 +1,7 @@ /*************************************************************************************************** * -* Copyright (c) 2013, 2014, 2015, 2016, 2017 Universitat Politecnica de Valencia - www.upv.es +* Copyright (c) 2013 - 2026 Universitat Politecnica de Valencia - www.upv.es +* Copyright (c) 2018 - 2026 Open Universiteit - www.ou.nl * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -27,16 +28,11 @@ * POSSIBILITY OF SUCH DAMAGE. *******************************************************************************************************/ - -/** - * @author Sebastian Bauersfeld - */ package org.testar.monkey.alayer.windows; -import org.testar.monkey.Proc; import org.testar.monkey.alayer.exceptions.ActionFailedException; -public final class WinProcessActivator implements Proc { +public final class WinProcessActivator implements Runnable { private final long pid; public WinProcessActivator(long pid){ this.pid = pid; }