示例#1
1
 /**
  * Factory method, equivalent to a "fromXML" for step creation. Looks for a class with the same
  * name as the XML tag, with the first letter capitalized. For example, <call /> is
  * abbot.script.Call.
  */
 public static Step createStep(Resolver resolver, Element el) throws InvalidScriptException {
   String tag = el.getName();
   Map attributes = createAttributeMap(el);
   String name = tag.substring(0, 1).toUpperCase() + tag.substring(1);
   if (tag.equals(TAG_WAIT)) {
     attributes.put(TAG_WAIT, "true");
     name = "Assert";
   }
   try {
     name = "abbot.script." + name;
     Log.debug("Instantiating " + name);
     Class cls = Class.forName(name);
     try {
       // Steps with contents require access to the XML element
       Class[] argTypes = new Class[] {Resolver.class, Element.class, Map.class};
       Constructor ctor = cls.getConstructor(argTypes);
       return (Step) ctor.newInstance(new Object[] {resolver, el, attributes});
     } catch (NoSuchMethodException nsm) {
       // All steps must support this ctor
       Class[] argTypes = new Class[] {Resolver.class, Map.class};
       Constructor ctor = cls.getConstructor(argTypes);
       return (Step) ctor.newInstance(new Object[] {resolver, attributes});
     }
   } catch (ClassNotFoundException cnf) {
     String msg = Strings.get("step.unknown_tag", new Object[] {tag});
     throw new InvalidScriptException(msg);
   } catch (InvocationTargetException ite) {
     Log.warn(ite);
     throw new InvalidScriptException(ite.getTargetException().getMessage());
   } catch (Exception exc) {
     Log.warn(exc);
     throw new InvalidScriptException(exc.getMessage());
   }
 }
示例#2
0
 /**
  * Return whether an event was generated. Assumes a SemanticRecorder is active.
  *
  * @throws RecordingFailedException if an error was encountered.
  */
 private boolean saveSemanticEvent() throws RecordingFailedException {
   Log.log("Storing event from current semantic recorder");
   try {
     Step step = semanticRecorder.getStep();
     if (step != null) {
       insertStep(step);
       setStatus("Added " + step);
     } else {
       setStatus("No semantic event found, events skipped");
     }
     semanticRecorder = null;
     return step != null;
   } catch (BugReport bug) {
     // changed to windowtester exception
     //   throw new RecordingFailedException(bug);
     throw new com.windowtester.swing.recorder.RecordingFailedException(bug);
   } catch (Exception e) {
     Log.log("Recording failed when saving action: " + e);
     // 1/3/07 kp: change message to windowtester message
     // String msg = Strings.get("editor.recording.exception");
     String msg = "Windowtester recording exception";
     //     throw new RecordingFailedException(new BugReport(msg, e));
     throw new com.windowtester.swing.recorder.RecordingFailedException(new BugReport(msg, e));
   }
 }
示例#3
0
  /**
   * Handle an event. This can either be ignored or contribute to the recording. For a given event,
   * if no current semantic recorder is active, select one based on the event's component. If the
   * semantic recorder accepts the event, then it is used to consume each subsequent event, until
   * its recordEvent method returns true, indicating that the semantic event has completed.
   */
  protected void recordEvent(java.awt.AWTEvent event) throws RecordingFailedException {

    // Discard any key/button release events at the start of the recording.
    if (steps.size() == 0 && event.getID() == KeyEvent.KEY_RELEASED) {
      Log.log("Ignoring initial release event");
      return;
    }

    SemanticRecorder newRecorder = null;

    // Process extraneous key modifiers used to simulate mouse buttons
    // Only check events while we have no semantic recorder, though,
    // because we wish to ignore everything between the modifiers
    if (Platform.isMacintosh() && semanticRecorder == null) {
      if (pruneClickModifiers(event)) return;
    }

    if (semanticRecorder == null) {
      SemanticRecorder sr =
          (event.getSource() instanceof Component)
              ? getSemanticRecorder((Component) event.getSource())
              // Use ComponentRecorder for MenuComponents
              : getSemanticRecorder(Component.class);
      if (sr.accept(event)) {
        semanticRecorder = newRecorder = sr;
        setStatus("Recording semantic event with " + sr);
        if (event.getSource() instanceof JInternalFrame) {
          // Ideally, adding an extra listener would be done by the
          // JInternalFrameRecorder, but the object needs more state
          // than is available to the recorder (notably to be able
          // to send events to the primary recorder).  If something
          // else turns up similar to this, then the EventRecorder
          // should be made available to the semantic recorders.
          //
          // Must add a listener, since COMPONENT_HIDDEN is not sent
          // on JInternalFrame close (1.4.1).
          JInternalFrame f = (JInternalFrame) event.getSource();
          new InternalFrameWatcher(f);
        }
      }
    }

    // If we're currently recording a semantic event, continue to do so
    if (semanticRecorder != null) {
      boolean consumed = semanticRecorder.record(event);
      boolean finished = semanticRecorder.isFinished();
      if (finished) {
        Log.debug("Semantic recorder is finished");
        saveSemanticEvent();
      }
      // If not consumed, need to check for semantic recorder (again)
      // (but avoid recursing indefinitely)
      if (!consumed && newRecorder == null) {
        Log.debug("Event was not consumed, parse it again");
        recordEvent(event);
      }
    } else {
      captureRawEvent(event);
    }
  }
示例#4
0
 /** Remove keypress events preceding and following ActionMap actions. */
 private void removeShortcutModifierKeyPresses() {
   int current = 0;
   int mask = Toolkit.getDefaultToolkit().getMenuShortcutKeyMask();
   String modifier = AWT.getKeyCode(AWT.maskToKeyCode(mask));
   while (current < steps.size()) {
     Step step = (Step) steps.get(current);
     if (isKey(step, modifier, PRESS)) {
       Log.debug("Found possible extraneous modifier");
       int keyDown = current;
       Action action = null;
       while (++current < steps.size()) {
         step = (Step) steps.get(current);
         if (step instanceof Action) {
           if ("actionActionMap".equals(((Action) step).getMethodName())) {
             action = (Action) step;
             continue;
           }
         } else if (isKey(step, modifier, RELEASE)) {
           if (action != null) {
             Log.debug("Removing extraneous shortcut modifier");
             steps.remove(current);
             steps.remove(keyDown);
             current = keyDown - 1;
           }
         }
         break;
       }
     }
     ++current;
   }
 }
示例#5
0
 /**
  * For use by subclasses when an error is encountered during parsing. Should only be used by the
  * XML parsing ctors.
  */
 protected void setScriptError(Throwable thr) {
   if (invalidScriptError == null) {
     invalidScriptError = thr;
   } else {
     Log.warn("More than one script error encountered: " + thr);
     Log.warn("Already have: " + invalidScriptError);
   }
 }
示例#6
0
 public Step(Resolver resolver, Map attributes) {
   this(resolver, "");
   Log.debug("Instantiating " + getClass());
   if (Log.expectDebugOutput) {
     Iterator iter = attributes.keySet().iterator();
     while (iter.hasNext()) {
       String key = (String) iter.next();
       Log.debug(key + "=" + attributes.get(key));
     }
   }
   parseStepAttributes(attributes);
 }
示例#7
0
 /** Convert the attributes in the given XML Element into a Map of name/value pairs. */
 protected static Map createAttributeMap(Element el) {
   Log.debug("Creating attribute map for " + el);
   Map attributes = new HashMap();
   Iterator iter = el.getAttributes().iterator();
   while (iter.hasNext()) {
     Attribute att = (Attribute) iter.next();
     attributes.put(att.getName(), att.getValue());
   }
   return attributes;
 }
  /** Parse clicks to cancel the recording if we get a click that's not in the JList (or ESC). */
  protected boolean parseClick(AWTEvent event) {

    if (isFinished()) {
      return false;
    }

    // FIXME add key-based activation/termination?
    boolean consumed = true;
    if (combo == null) {
      combo = getComboBox(event);
      listener =
          new ActionListener() {
            public void actionPerformed(ActionEvent ev) {
              index = combo.getSelectedIndex();
              if (!combo.isPopupVisible()) {
                combo.removeActionListener(listener);
                setFinished(true);
              }
            }
          };
      combo.addActionListener(listener);
      setStatus("Waiting for selection");
    } else if (event.getID() == KeyEvent.KEY_RELEASED
        && (((KeyEvent) event).getKeyCode() == KeyEvent.VK_SPACE
            || ((KeyEvent) event).getKeyCode() == KeyEvent.VK_ENTER)) {
      index = combo.getSelectedIndex();
      setFinished(true);
    }
    // Cancel via click somewhere else
    else if (event.getID() == MouseEvent.MOUSE_PRESSED
        && !AWT.isOnPopup((Component) event.getSource())
        && combo != getComboBox(event)) {
      setFinished(true);
      consumed = false;
    }
    // Cancel via ESC key
    else if (event.getID() == KeyEvent.KEY_RELEASED
        && ((KeyEvent) event).getKeyCode() == KeyEvent.VK_ESCAPE) {
      setStatus("Selection canceled");
      setFinished(true);
    } else {
      Log.debug("Event ignored");
    }
    if (list == null && combo.isPopupVisible()) list = tester.findComboList(combo);

    if (isFinished()) {
      combo.removeActionListener(listener);
      listener = null;
    }

    return consumed;
  }
 /** Compare two images. May be BufferedImages or File arguments. */
 public int compare(Object obj1, Object obj2) {
   try {
     obj1 = convertToJPEGFile(obj1);
   } catch (IOException io) {
     obj1 = null;
   }
   try {
     obj2 = convertToJPEGFile(obj2);
   } catch (IOException io) {
     obj2 = null;
   }
   Log.debug("Comparing " + obj1 + " and " + obj2);
   return comparator.compare(obj1, obj2);
 }
示例#10
0
 /** Provide a one-line XML string representation. */
 public static String toXMLString(XMLifiable obj) {
   // Comments are the only things that aren't actually elements...
   if (obj instanceof Comment) {
     return "<!-- " + ((Comment) obj).getDescription() + " -->";
   }
   Element el = obj.toXML();
   StringWriter writer = new StringWriter();
   try {
     XMLOutputter outputter = new XMLOutputter();
     outputter.output(el, writer);
   } catch (IOException io) {
     Log.warn(io);
   }
   return writer.toString();
 }
示例#11
0
 /** Add an attribute to the given XML Element. Attributes are kept in alphabetical order. */
 protected Element addAttributes(Element el) {
   // Use a TreeMap to keep the attributes sorted on output
   Map atts = new TreeMap(getAttributes());
   Iterator iter = atts.keySet().iterator();
   while (iter.hasNext()) {
     String key = (String) iter.next();
     String value = (String) atts.get(key);
     if (value == null) {
       Log.warn("Attribute '" + key + "' value was null in step " + getXMLTag());
       value = "";
     }
     el.setAttribute(key, value);
   }
   return el;
 }
示例#12
0
 private static File convertToJPEGFile(Object obj) throws IOException {
   if (obj != null) {
     if (obj instanceof String) {
       obj = new File((String) obj);
     }
     if (obj instanceof BufferedImage) {
       File file = File.createTempFile("ImageComparator", ".jpg");
       Log.debug("Creating " + file);
       writeJPEG(file, (BufferedImage) obj);
       file.deleteOnExit();
       return file;
     }
     if (obj instanceof File) {
       return (File) obj;
     }
   }
   return null;
 }
示例#13
0
 /** Return the semantic recorder for the given component class. */
 protected SemanticRecorder getSemanticRecorder(Class cls) {
   // 	System.out.println("getting recorder for: " + cls);
   if (!(Component.class.isAssignableFrom(cls))) {
     throw new IllegalArgumentException("Class (" + cls + ") must derive from " + "Component");
   }
   SemanticRecorder sr = (SemanticRecorder) semanticRecorders.get(cls);
   if (sr == null) {
     Class ccls = Robot.getCanonicalClass(cls);
     if (ccls != cls) {
       sr = getSemanticRecorder(ccls);
       // Additionally cache the mapping from the non-canonical class
       semanticRecorders.put(cls, sr);
       return sr;
     }
     String cname = Robot.simpleClassName(cls);
     try {
       // cname = "abbot.editor.recorder." + cname + "Recorder";
       cname = getRecoderName(cname);
       Class recorderClass = Class.forName(cname);
       Constructor ctor =
           recorderClass.getConstructor(
               new Class[] {
                 Resolver.class,
               });
       sr = (SemanticRecorder) ctor.newInstance(new Object[] {getResolver()});
       sr.addActionListener(getListener());
     } catch (InvocationTargetException e) {
       Log.warn(e);
     } catch (NoSuchMethodException e) {
       sr = getSemanticRecorder(cls.getSuperclass());
     } catch (InstantiationException e) {
       sr = getSemanticRecorder(cls.getSuperclass());
     } catch (IllegalAccessException iae) {
       sr = getSemanticRecorder(cls.getSuperclass());
     } catch (ClassNotFoundException cnf) {
       sr = getSemanticRecorder(cls.getSuperclass());
     }
     // Cache the results for future reference
     semanticRecorders.put(cls, sr);
   }
   return sr;
 }
示例#14
0
  /**
   * Copies the gold folder to the runtime workspace CONTRACT: folder exists in the devspace,
   * goldFolder has been set In this implementation, the gold folder is copied from
   * bin/test/GoldFolder
   */
  public static void copyGoldFolder() {
    /* goldFolder (location where goldfolder should go in runspace) must not be null */
    Assert.assertTrue(goldFolder != null);

    Bundle model2testsBundle = EclipsePlugin.getDefault().getBundle();
    /* this is the source for our goldfolder in the devspace that we're copying to the runspace */
    URL gfURL = model2testsBundle.getEntry("/");

    /* devspace GoldFolder must exist */
    // Assert.assertTrue(goldFolder.exists());
    // Assert.assertTrue(gf.exists());
    IWorkspace workspace = ResourcesPlugin.getWorkspace();
    IWorkspaceRoot workspaceRoot = workspace.getRoot();
    IPath rootPath = workspaceRoot.getLocation();
    try {
      gfURL = Platform.asLocalURL(gfURL);
    } catch (IOException e) {
      e.printStackTrace();
    }
    System.out.println("URL path: " + gfURL.getPath());
    System.out.println("URL file: " + gfURL.getFile());
    System.out.println("URL ref: " + gfURL.getRef());
    File srcDir = new File(gfURL.getPath(), "GoldFolder");
    Path p = new Path(gfURL.getPath());
    IResource igf = ((Workspace) workspace).newResource(p, IResource.FOLDER);
    IPath gfpath = goldFolder.getFullPath();
    File destDir = new File(gfpath.toOSString());
    /* Make sure both of these directories exist */
    System.out.println("Source directory exists: " + srcDir.exists());
    /* destination directory shouldn't exist because we're going to create it */
    // System.out.println ("Dest directory exists: " + destDir.exists());
    /* Since assert isn't working for the moment... */
    if (!srcDir.exists()) {
      System.out.println("GoldFolder not found");
      Log.log("GoldFolder not found");
      Assert.fail("GoldFolder not found");
    }
    //		Assert.assertTrue("Source goldfolder does not exist", srcDir.exists());
    //		Assert.assertTrue("Destination goldfolder does not exist", destDir.exists());
    copyFolder(srcDir, destDir);
  }
示例#15
0
  /** Capture the given event as a raw event. */
  private void captureRawEvent(AWTEvent event) {

    // FIXME maybe measure time delay between events and insert delay
    // events?
    int id = event.getID();
    boolean capture = false;
    switch (id) {
      case MouseEvent.MOUSE_PRESSED:
      case MouseEvent.MOUSE_RELEASED:
        capture = true;
        break;
      case KeyEvent.KEY_PRESSED:
      case KeyEvent.KEY_RELEASED:
        KeyEvent e = (KeyEvent) event;
        capture = e.getKeyCode() != KeyEvent.VK_UNDEFINED;
        if (!capture) {
          Log.warn(
              "VM bug: no valid keycode on key "
                  + (id == KeyEvent.KEY_PRESSED ? "press" : "release"));
        }
        break;
      case MouseEvent.MOUSE_ENTERED:
      case MouseEvent.MOUSE_EXITED:
        //     case MouseEvent.MOUSE_MOVED:
      case MouseEvent.MOUSE_DRAGGED:
        capture = captureMotion;
        break;
      default:
        break;
    }
    if (capture) {
      Event step = new Event(getResolver(), null, event);
      capturedEvent = event;
      insertStep(step);
      setStatus("Added event " + step);
    }
  }
示例#16
0
 /** Only exposed so that Script may invoke it on load from disk. */
 protected final void parseStepAttributes(Map attributes) {
   Log.debug("Parsing attributes for " + getClass());
   description = (String) attributes.get(TAG_DESC);
 }
示例#17
0
 /**
  * Main run method. Should <b>never</b> be run on the event dispatch thread, although no check is
  * explicitly done here.
  */
 public final void run() throws Throwable {
   if (invalidScriptError != null) throw invalidScriptError;
   Log.debug("Running " + toString());
   runStep();
 }
示例#18
0
 public void terminate() throws RecordingFailedException {
   Log.log("EventRecorder terminated");
   if (semanticRecorder != null) {
     saveSemanticEvent();
   }
 }