changeset 19:28044ad4f002

7902156: Implement clickOnReference(reference) API on JEditorPaneOperator Reviewed-by: shurailine Contributed-by: abdul.kolarkunnu@oracle.com
author akolarkunnu
date Thu, 09 Aug 2018 18:00:36 -0700
parents ca5106c73209
children f30f9f4aad4c
files src/org/netbeans/jemmy/operators/JEditorPaneOperator.java src/org/netbeans/jemmy/version_info test/org/netbeans/jemmy/operators/JEditorPaneOperatorTest.java test/org/netbeans/jemmy/operators/resources/page1.html test/org/netbeans/jemmy/operators/resources/page2.html
diffstat 5 files changed, 278 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/src/org/netbeans/jemmy/operators/JEditorPaneOperator.java	Thu Aug 09 08:20:22 2018 -0700
+++ b/src/org/netbeans/jemmy/operators/JEditorPaneOperator.java	Thu Aug 09 18:00:36 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,18 +25,27 @@
 package org.netbeans.jemmy.operators;
 
 import java.awt.Container;
+import java.awt.IllegalComponentStateException;
+import java.awt.Point;
+import java.awt.Rectangle;
 import java.io.IOException;
 import java.io.InputStream;
 import java.net.URL;
 import java.util.Hashtable;
 
 import javax.swing.JEditorPane;
+import javax.swing.JScrollPane;
 import javax.swing.event.HyperlinkEvent;
 import javax.swing.event.HyperlinkListener;
+import javax.swing.text.Document;
 import javax.swing.text.EditorKit;
+import javax.swing.text.html.HTML;
+import javax.swing.text.html.HTMLDocument;
 
 import org.netbeans.jemmy.ComponentChooser;
+import org.netbeans.jemmy.ComponentSearcher;
 import org.netbeans.jemmy.TimeoutExpiredException;
+import org.netbeans.jemmy.util.EmptyVisualizer;
 
 /**
  * Class provides basic functions to operate with JEditorPane (selection,
@@ -295,6 +304,72 @@
         return result;
     }
 
+    /**
+     * Clicks on a named reference location
+     *
+     * @param reference the named location to click
+     */
+    public void clickOnReference(String reference) {
+        int expectedCaretPos = getCaretPositionOfReference(reference);
+        Rectangle viewBounds = modelToView(expectedCaretPos);
+        Point expectedCaretPosLoc = new Point(viewBounds.x, viewBounds.y);
+        //TODO Extend DefaultVisualizer to show a portion of component and use
+        // that in here
+        JScrollPane scroll = (JScrollPane) getContainer(
+                new JScrollPaneOperator.JScrollPaneFinder(
+                        ComponentSearcher.getTrueChooser("JScrollPane")));
+        if (scroll != null) {
+            JScrollPaneOperator scroller = new JScrollPaneOperator(scroll);
+            scroller.copyEnvironment(this);
+            scroller.setVisualizer(new EmptyVisualizer());
+            scroller.scrollToComponentRectangle(getSource(),
+                    (int) viewBounds.getX(), (int) viewBounds.getY(),
+                    (int) viewBounds.getWidth(), (int) viewBounds.getHeight());
+            setCaretPosition(expectedCaretPos);
+        } else if (getVisibleRect().contains(expectedCaretPosLoc)) {
+            scrollToReference(reference);
+        } else {
+            throw new IllegalComponentStateException("Component doesn't "
+                    + "contain JScrollPane and Reference is out of"
+                    + " visible area");
+        }
+
+        waitStateOnQueue(comp -> expectedCaretPosLoc.equals(
+                ((JEditorPane)comp).getCaret().getMagicCaretPosition()));
+        waitCaretPosition(expectedCaretPos);
+        clickMouse(viewBounds.x, viewBounds.y, 1);
+    }
+
+    /**
+     * Gets the starting caret position of a named reference location
+     *
+     * @param reference the named location
+     * @return starting caret position of the named reference location
+     * @throws IllegalArgumentException if the named reference doesn't
+     *  exist in the document
+     */
+    private int getCaretPositionOfReference(String reference)
+            throws IllegalArgumentException {
+        int pos = -1;
+        Document doc = getDocument();
+        if (doc instanceof HTMLDocument) {
+            HTMLDocument.Iterator iter =
+                    ((HTMLDocument) doc).getIterator(HTML.Tag.A);
+            for (;iter.isValid();iter.next()) {
+                String nameAttr = (String) iter.getAttributes().
+                        getAttribute(HTML.Attribute.NAME);
+                if (reference.equals(nameAttr)) {
+                    pos = iter.getStartOffset();
+                }
+            }
+        }
+        if(pos ==-1) {
+            throw new IllegalArgumentException("Reference " + reference +
+                    " doesn't exist in the document " + doc + ".");
+        }
+        return pos;
+    }
+
     ////////////////////////////////////////////////////////
     //Mapping                                             //
     /**
@@ -457,6 +532,18 @@
         });
     }
 
+    /**
+     * Maps {@code JEditorPane.scrollToReference(String)} through queue
+     */
+    public void scrollToReference(String reference) {
+        runMapping(new MapVoidAction("scrollToReference") {
+            @Override
+            public void map() throws IOException {
+                ((JEditorPane) getSource()).scrollToReference(reference);
+            }
+        });
+    }
+
     //End of mapping                                      //
     ////////////////////////////////////////////////////////
     /**
--- a/src/org/netbeans/jemmy/version_info	Thu Aug 09 08:20:22 2018 -0700
+++ b/src/org/netbeans/jemmy/version_info	Thu Aug 09 18:00:36 2018 -0700
@@ -1,6 +1,6 @@
 Manifest-version: 1.0
 Main-Class: org.netbeans.jemmy.JemmyProperties
 Jemmy-MajorVersion: 3.0
-Jemmy-MinorVersion: 2.0
+Jemmy-MinorVersion: 3.0
 Jemmy-Build: @BUILD_NUMBER@
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/org/netbeans/jemmy/operators/JEditorPaneOperatorTest.java	Thu Aug 09 18:00:36 2018 -0700
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package org.netbeans.jemmy.operators;
+
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
+
+import java.awt.BorderLayout;
+import java.awt.Dimension;
+import java.awt.IllegalComponentStateException;
+import java.io.IOException;
+import java.net.URL;
+
+import javax.swing.JEditorPane;
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JViewport;
+import javax.swing.event.HyperlinkEvent;
+import javax.swing.event.HyperlinkListener;
+
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+public class JEditorPaneOperatorTest {
+
+    private final static String PAGE1 = "page1";
+    private final static String PAGE2 = "page2";
+    private final static String PAGE1_TEXT = "hi";
+    private final static String PAGE2_TEXT = "hello";
+    private final URL page1URL = getClass().getResource("resources/page1.html");
+    private JFrame frame;
+    private HyperlinkListener listener = null;
+
+    @BeforeClass
+    protected void setUp() throws Exception {
+        frame = new JFrame();
+        frame.setPreferredSize(new Dimension(800, 600));
+        frame.pack();
+        frame.setLocationRelativeTo(null);
+
+        listener = event -> {
+            if (event.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
+                try {
+                    ((JEditorPane)event.getSource()).setPage(event.getURL());
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+        };
+    }
+
+    @AfterClass
+    protected void tearDown() throws Exception {
+        frame.setVisible(false);
+        frame.dispose();
+    }
+
+    @Test
+    public void testClickOnReferenceWithScrollPane() throws IOException {
+        JEditorPane editorPane = new JEditorPane(page1URL);
+        editorPane.setEditable(false);
+
+        JScrollPane scroller = new JScrollPane();
+        JViewport vp = scroller.getViewport();
+        vp.add(editorPane);
+
+        JPanel panel = new JPanel();
+        panel.setLayout(new BorderLayout());
+        panel.add(scroller, BorderLayout.CENTER);
+        frame.getContentPane().add(panel);
+        frame.setVisible(true);
+        JEditorPaneOperator editorPaneOperator =
+                new JEditorPaneOperator(new FrameOperator(frame));
+        checkPageLoaded(editorPaneOperator, PAGE1, PAGE1_TEXT);
+
+        // Testing reference which doesn't exist
+        String excepMessage = "";
+        try {
+            editorPaneOperator.clickOnReference(PAGE1);
+            fail();
+        } catch (IllegalArgumentException e) {
+            excepMessage = e.getMessage();
+        }
+        assertTrue(excepMessage.contains(
+                "Reference page1 doesn't exist in the document"));
+        try {
+            editorPaneOperator.addHyperlinkListener(listener);
+            // Testing on a short text page
+            editorPaneOperator.clickOnReference(PAGE2);
+            checkPageLoaded(editorPaneOperator, PAGE2, PAGE2_TEXT);
+
+            // Testing on a long text page
+            editorPaneOperator.clickOnReference(PAGE1);
+            editorPaneOperator.waitStateOnQueue(comp
+                    -> ((JEditorPane)comp).getPage().toString().contains(PAGE1));
+        } finally {
+            editorPane.removeHyperlinkListener(listener);
+            frame.getContentPane().remove(panel);
+        }
+    }
+
+    @Test
+    public void testClickOnReferenceWithoutScrollPane() throws IOException {
+        JEditorPane editorPane = new JEditorPane(page1URL);
+        editorPane.setEditable(false);
+        frame.getContentPane().add(editorPane);
+        frame.setVisible(true);
+        JEditorPaneOperator editorPaneOperator =
+                new JEditorPaneOperator(new JFrameOperator(frame));
+        checkPageLoaded(editorPaneOperator, PAGE1, PAGE1_TEXT);
+
+        try {
+            editorPaneOperator.addHyperlinkListener(listener);
+            // Testing reference on the visible area
+            editorPaneOperator.clickOnReference(PAGE2);
+            checkPageLoaded(editorPaneOperator, PAGE2, PAGE2_TEXT);
+
+            // Testing reference on the non-visible area
+            String excepMessage = "";
+            try {
+                editorPaneOperator.clickOnReference(PAGE1);
+                fail();
+            } catch (IllegalComponentStateException e) {
+                excepMessage = e.getMessage();
+            }
+            assertTrue(excepMessage.equals("Component doesn't contain"
+                    + " JScrollPane and Reference is out of visible area"));
+        } finally {
+            editorPaneOperator.removeHyperlinkListener(listener);
+            frame.getContentPane().remove(editorPane);
+        }
+    }
+
+    private void checkPageLoaded(JEditorPaneOperator editorPaneOperator,
+            String page, String text) {
+        editorPaneOperator.waitStateOnQueue(comp
+                -> ((JEditorPane)comp).getPage().toString().contains(page));
+        editorPaneOperator.selectText(text);
+        editorPaneOperator.waitStateOnQueue(comp
+                -> text.equals(editorPaneOperator.getSelectedText()));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/org/netbeans/jemmy/operators/resources/page1.html	Thu Aug 09 18:00:36 2018 -0700
@@ -0,0 +1,10 @@
+<html>
+<head>
+<title>Page 1</title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+</head>
+<body>
+Page 1 Body. hi
+<p><b><a href="page2.html" name="page2">Page2</a></b></p>
+</body>
+</html>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/org/netbeans/jemmy/operators/resources/page2.html	Thu Aug 09 18:00:36 2018 -0700
@@ -0,0 +1,12 @@
+<html>
+<head>
+<title>Page 2</title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+</head>
+<body>
+<p>Some long text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text. hello</p>
+<p>Some long text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text</p>
+<p>Some long text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text text Some long text</p>
+<p><b><a href="page1.html" name="page1">Page1</a></b></p>
+</body>
+</html>
\ No newline at end of file