Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
Clear All
new posts

    SelectItem AddChangedHandler not working

    I am working with AutoTest.js to build a custom add-in for QTP. The app I need to automate is using SmartGWT 2.5.

    I have a need to add a handler for the "changed" event of a SelectItem control. I am able to get a reference to the SelectItem and manipulate it. But I have been unable to get correct syntax to add the handler for the "changed" event.

    I have tried various versions of code but am not able to get it to fire.

    The code snippet that I thought would work is shown below:
    thisItem.addChangedHandler(new ChangedHandler() {
    public OnChanged(event) {
    var thisValue = event.getValue();
    //...code to work w/ Value goes here...
    return true;
    }
    });

    My end goal is to run some code when SelectItem value has changed. addChangedHandler seems ideal for this but I'm open to other approaches.

    Any help to point out my error or direct me to the correct working example is appreciated.

    #2
    There's nothing wrong with that tiny snippet of code and if you try adding similar code to any sample, it works. We'd need more information to identify why it's not working in your actual application.

    Comment


      #3
      I appreciate the fast reply.

      I have been able to get the event handlers to hook up using the QTP _util object. I have a new issue though. I am able to locate and setValue on the SelectItem control. But when I submit the form, the new value is ignored and the original value is used.

      For example, I have a dynamicForm with a SelectItem for OrderType. It is defaulted to NEW on load. I have JS that manipulates the SelectItem in the Select function in my QTP add-in. My Select function does some alerts and I see that I have updated the SelectItem control. I update the value to MOVE. Then I submit the form and the next page believes OrderType is still NEW instead of MOVE.

      Q: Am I missing any other code (such as dynamicForm event handling) that would complete the setValue() process?
      Q: Can I create an object such as "ChangedHandler" using the window.isc object (as I cannot seem to get a reference to com.smartgwt.client.widgets.form.fields.events namespace)?

      Thanks, Ralph

      ... the complete HP EA (QTP Extensibility Accelerator) control .JS file is shown below.
      ... The Select() function is where setValue() is being called.


      // *** Start of auto-generated code *** (please don't modify this section)
      ///<reference path="C:\Users\Ralph\AppData\Local\Temp\EA_IntelliTemp\rt41yle1.js" />
      _elem=qtpElemObject;
      _util=qtpUtilObject;
      // *** End of auto-generated code ***

      /////////////////////////////////////////////////////////////////////////////////////
      // UnOComboBoxPicker.js
      //
      // This file contains the implementation of the support for the vzUnO comboBoxPicker
      // control.
      //
      // This file is part of Ralph Pritchard's vzUnO add-in for QTP. It was created using
      // HP Extensibility Accelerator.
      //
      //////////////////////////////////////////////////////////////////////////////////////

      //////////////////////////////////////////////////////////////////////////////
      // This function is used to retrieve the run time values for the control's
      // identification properties (defined in the the vzUnOTestObjects.xml file).
      //
      // Parameters: property - The name of the property to retrieve.
      // Returns: Integer, String, Boolean, or Array.
      // The value of the requested property. No value is returned
      // if an error occurs or the specified property is not
      // supported by this method.
      //////////////////////////////////////////////////////////////////////////////
      function get_property_value(property) {
      _util.LogLine("get_property_value for property=" + property, LogSeverity_Information, 0, 9);
      if (property == "title" || property == "logical_name") {
      if (window.vzUnOWaitForPick == true) {
      //...use alternate method to identify the object
      //alert(window.vzUnOSelectItemID);
      returnValue = window.vzUnOSelectItemID;
      }
      else {
      var divElem = getDivElem(_elem);
      var returnValue = "UNKNOWN";
      if (divElem != null) {
      //return window.$(divElem).text();
      var thisHtmlControl = getImgElem(_elem);
      // DEV NOTE: There seems to be a length constraint on the $89 value.
      // If too long, it may truncate and that may result in some controls
      // being identified incorrectly if the IDs ($89 attribute on the <A> tag)
      // match up to the point of truncation. It may be possible to substring
      // when $89.value is too long but even that could still lead to incorrect
      // identification.
      returnValue = thisHtmlControl.$89;
      }
      }
      return returnValue;
      }
      if (property == "state") {
      switch (getComboboxState(_elem)) {
      case COMBOBOX_STATE_DEFAULTED:
      return "Defaulted";
      case COMBOBOX_STATE_MODIFIED:
      return "Modified";
      }
      }
      }

      ///////////////////////////////////////////////////////////////////////////////
      // This function is used by Ralph for debugging.
      //
      // Returns: Boolean: true for success, false for error.
      ///////////////////////////////////////////////////////////////////////////////
      function RalphsDebug() {
      var reportStatus = micDone;
      alert("RalphsDebug method is a test method used to debug the EA code.\r\nUsually, you will modify UnOComboBoxPicker.js for your custom debug needs.");
      return reportStatus;
      }

      ///////////////////////////////////////////////////////////////////////////////
      // Select function supports the Select test object method.
      // Given the DOM element associated with the SelectItem control and the
      // desired value, locate the SmartGWT SelectItem control and change its value.
      // If the SelectItem control is not found, an error occurs.
      //
      // The Select function is usually used to playback a recording.
      //
      // Returns: Boolean: true for success, false for error.
      ///////////////////////////////////////////////////////////////////////////////
      function Select(scitem, option) {
      var reportStatus = micDone;
      var reportMsg = "Option '" + option + "' was selected.";

      //alert("RALPH: SELECT running with option=" + option + "\r\n" + scitem);
      var domItem = window.isc.AutoTest.getElement(scitem);
      //alert("2");
      if (domItem != null) {
      var dynamicForm = window.isc.AutoTest.locateCanvasFromDOMElement(domItem);
      if (dynamicForm != null) {
      var formitems = dynamicForm.getFields();
      for (var i = 0; i < formitems.length; i++) {
      var thisItem = formitems[i];
      var thisItemClass = thisItem.Class;
      if (thisItemClass == "SelectItem") {
      if (thisItem.getID() == scitem) {
      //alert("!!!Super FIND!");
      break;
      }
      }
      }
      }

      domItem.click();
      // The alert will show SelectItem now has the OLD value
      alert("3 SelectItem.ID=" + thisItem.getID() + " : value=" + thisItem.getValue());
      thisItem.setValue(option);
      // The alert will show SelectItem now has the NEW value
      alert("4 SelectItem.ID=" + thisItem.getID() + " : value=" + thisItem.getValue());
      }

      _util.Report(reportStatus, "Select", toSafeArray(new Array()), reportMsg);

      return reportStatus;
      }

      ///////////////////////////////////////////////////////////////////////////////
      // Set function supports the Set test object method.
      // Given the desired value, locate the SmartGWT SelectItem control and change
      // its value.
      // If the SelectItem control is not found, an error occurs.
      //
      // The Set function is usually used in scripting while the Select method is
      // usually created by Record/Playback.
      //
      // Returns: Boolean: true for success, false for error.
      ///////////////////////////////////////////////////////////////////////////////
      function Set(option) {
      //alert("RALPH: select option=" + option);
      var reportStatus = micDone;
      var reportMsg = "Option '" + option + "' was set.";

      var thisHtmlControl = getImgElem(_elem);
      var dynamicForm = window.isc.AutoTest.locateCanvasFromDOMElement(_elem);
      if (dynamicForm != null) {
      var formTop = dynamicForm.getPageTop();
      var formLeft = dynamicForm.getPageLeft();

      var formitems = dynamicForm.getFields();
      for (var i = 0; i < formitems.length; i++) {
      var thisItem = formitems[i];
      var thisItemClass = thisItem.Class;
      if (thisItemClass == "SelectItem") {
      //alert("DOM : $89(SelectItemID) = " + thisHtmlControl.$89 + "\r\n" + "ITEM : ID=" + thisItem.getID());
      if (thisItem.getID() == thisHtmlControl.$89) {
      //alert("found it!");
      var isValid = IsValueValid(option, thisItem);
      if (isValid == true) {
      thisItem.setValue(option);
      }
      else {
      reportMsg = "Option '" + option + "' is not found! (SelectItem.valueMap does not contain this option.)";
      reportStatus = micFail;
      }
      break;
      }
      }
      }
      }

      _util.Report(reportStatus, "Set", toSafeArray(new Array()), reportMsg);

      return reportStatus;
      }

      ////////////////////////////////////////////////////////////////////////////////
      // ListenToEvents function is used to register for events that are specific to this
      // control to support recording.
      //
      // Parameter: elem - A reference to the element object.
      // The function does not use this parameter. It uses _elem, because
      // then it can make assumptions about the structure of the element,
      // because there are certain conditions that the element must have
      // met to be identified as the main control that QuickTest is now
      // handling.
      // Returns: Boolean: true for success, false for error.
      ///////////////////////////////////////////////////////////////////////////////////
      function ListenToEvents( elem )
      {
      // Register the click events on the SelectItem DIV element because this is how a
      // a user expands and collapses the DisclosurePanel.
      var divElem = getDivElem(_elem);
      if (divElem == null)
      return false;
      _util.RegisterForEvent(divElem, "onclick", "OnSelect");

      // Register the click events on each of the hidden Options tables. The tables
      // appear when the DIV is clicked to the user can select the desired option.
      var theOptionsTable = window.$("table.listTable");
      for(var i=0; i<theOptionsTable.length; i++) {
      var thisTable = theOptionsTable[i];
      _util.RegisterForEvent(thisTable, "onclick", "OnSelectContinue");
      }

      return true;
      }

      //////////////////////////////////////////////////////////////////////////////
      // OnSelect function is called during a recording session when the user clicks
      // the DIV containing the SmartGWT SelectItem control.
      // When this event handler fires, the user has clicked a SelectItem control
      // but the value has not yet been selected. OnSelectContinue will fire when
      // the value is selected.
      //
      // Therefore, this function needs to save a reference to the clicked element.
      // OnSelectContinue will then use that reference to know which SelectItem is
      // currently being modified.
      //
      // Returns: Boolean: true for success, false for error.
      ///////////////////////////////////////////////////////////////////////////////
      function OnSelect() {
      _util.LogLine("OnSelect event",
      LogSeverity_Information, 0, 9);

      window.vzUnOLastElement = _elem;

      var arr = new Array();
      _util.Record("Click", toSafeArray(arr), 0);

      return true;
      }

      //////////////////////////////////////////////////////////////////////////////
      // OnSelectContinue function is called during a recording session when the
      // user selects the new value for a SmartGWT SelectItem control.
      // When this event handler fires, the user has clicked the desired option
      // for a SelectItem control. A past click event (OnSelect) has stored a
      // reference to the SelectItem. This function must now record the actual
      // .Select call into the QTP script.
      //
      // Returns: Boolean: true for success, false for error.
      ///////////////////////////////////////////////////////////////////////////////
      function OnSelectContinue() {
      var currentValue = "";
      var LastElement = window.vzUnOLastElement;
      var dynamicForm = window.isc.AutoTest.locateCanvasFromDOMElement(LastElement);
      if (dynamicForm != null) {
      var formitems = dynamicForm.getFields();
      // alert("formitems.length=" + formitems.length);
      var thisHtmlControl = getImgElem(LastElement);
      if (thisHtmlControl != null) {
      for (var i = 0; i < formitems.length; i++) {
      var thisItem = formitems[i];
      var thisItemClass = thisItem.Class;
      if (thisItem.getID() == thisHtmlControl.$89) {
      thisSmartControlID = thisItem.getID()
      currentValue = thisItem.getValue();
      //alert("FOUND IT!!!" + "\r\n" + "thisSmartControlID=" + thisSmartControlID + "\r\n" + "currentValue=" + currentValue);
      }
      }
      }
      }

      _util.LogLine("OnSelectContinue event",
      LogSeverity_Information, 0, 9);

      if (String(currentValue) != "undefined") {
      var arr = new Array();
      arr[0] = String(thisSmartControlID);
      arr[1] = String(currentValue);
      _util.Record("Select", toSafeArray(arr), 0);
      }

      return true;
      }

      /////////////////////////////////////////////////////////////////////////////////
      //
      // The following functions are helper functions used internally in this file.
      //
      /////////////////////////////////////////////////////////////////////////////////

      //////////////////////////////////////////////////////////////////////////////////
      // getDivElem returns the HTML element that contains the icon IMG of the
      // comboBoxPicker control.
      //
      // Parameters: ComboBoxPickerElem - The HTML element of the comboBoxPicker control.
      // Returns: The icon DIV HTML element of the comboBoxPicker, null upon error.
      //////////////////////////////////////////////////////////////////////////////////
      function getDivElem(comboBoxPickerElem) {
      // Make sure the element is a DIV element where the current value appears.
      return window.$(comboBoxPickerElem).find("div").get(0);
      }

      //////////////////////////////////////////////////////////////////////////////////
      // getImgElem returns the HTML element that contains the icon IMG of the
      // comboBoxPicker control.
      //
      // Parameters: ComboBoxPickerElem - The HTML element of the comboBoxPicker control.
      // Returns: The icon IMG HTML element of the comboBoxPicker, null upon error.
      //////////////////////////////////////////////////////////////////////////////////
      function getImgElem(comboBoxPickerElem) {
      // Make sure the element is a IMG element usually containing a down arrow icon.
      return window.$(comboBoxPickerElem).find("a").get(0);
      }

      //////////////////////////////////////////////////////////////////////////////////
      // getOptionElements returns the HTML element that contains the icon IMG of the
      // comboBoxPicker control.
      //
      // Parameters: ComboBoxPickerElem - The HTML element of the comboBoxPicker control.
      // Returns: A collection of options (NOBR HTML elements) of the comboBoxPicker, null upon error.
      //////////////////////////////////////////////////////////////////////////////////
      function getOptionElements(comboBoxPickerElem) {
      // Make sure the element is a NOBR element.
      return window.$(comboBoxPickerElem).find("nobr");
      }

      ///////////////////////////////////////////////////////////////////////////////
      // IsValueValid checks to see if the option is in the SelectItem's values
      ///////////////////////////////////////////////////////////////////////////////
      function IsValueValid(thisValue, thisSelectItem) {
      var valueMap = thisSelectItem.getValueMap();
      var values = window.isc.getValues(valueMap);
      for (var j = 0; j < values.length; j++) {
      var currentValue = values[j];
      if (thisValue == currentValue) {
      return true;
      }
      }
      return false;
      }

      //////////////////////////////////////////////////////////////////////////////
      // This function is NOT currently used. It will be used to replace XML
      // "object identification" to allow multiple sub-controls to be identified
      // as the same SmartGWT SelectItem control instead of individual WebElements.
      // DEV: This starter code came from the GWT add-in, GWTToggleButton.js.
      //////////////////////////////////////////////////////////////////////////////
      function isSelectItem() {
      var suspectedElem = window.$(_elem);

      // If this has the unexpanded SelectItem class, then it's one of ours
      if (suspectedElem.parent().next().get(0) && suspectedElem.parent().next().get(0).ToggleButtonBehavior) {
      return suspectedElem.parent().next().get(0);
      }

      if (suspectedElem.next().get(0) && suspectedElem.next().get(0).ToggleButtonBehavior) {
      return suspectedElem.next().get(0);
      }

      if (_elem.ToggleButtonBehavior) {
      return _elem;
      }

      return false;
      }

      Comment


        #4
        We can't run this code to see what's wrong, but we can tell you that there's no obvious problem with your setValue() call. Something may be changing the value later.

        As far as adding a GWT change handler, this is only possible if you use JSNI to set up a JavaScript function that can do this, otherwise, GWT generates obfuscated code so there is no way for JavaScript to create instances or call methods.

        Comment


          #5
          I believe I need to call the changed() event handler attached to the SelectItem. If I call it as "thisItem.changed()", I end up w/ a form that doesn't fully sumbit. I suspect I am not calling it w/ the correct parms.

          Q: What is the signature for a "changed" event handler? Is there doc which discusses creating a "changed" even handler for a formItem?

          Thanks for the fast replies,
          Ralph

          Comment


            #6
            It's invalid to call this directly. You must trigger it by causing the browser to fire events, similar to what Selenium does.

            Comment


              #7
              Excellent advice! I appreciate the fast replies. Now that I've taken your approach of manipulating the controls purely from the testing tool, things are working much better.

              I've approached it using QTP methods wired using EA _util via my custom add-in. I also have Selenium scipts from my dev team and the scLocators from them were also helpful. Those scripts also confirmed they were doing it with clicks in the testing tool - much as you suggested.

              So far, I'm able to eliminate most of my custom addin JS and just use the QTP WebElement Click event. But, I like being able to use calls like "window.isc.AutoTest.locateCanvasFromDOMElement(domItem)" when I need to check out something from the SmartGWT controls.... 1 control down, 5 more to go!

              Thanks again!

              Comment


                #8
                We'd also recommend taking a look at a 3.1d build (even if you can't use it yet) to see the expanded documentation and best practices information around Selenium, as well as several additional Selenium commands that you might want to replicate.

                Comment


                  #9
                  Originally posted by dt08412a View Post
                  Excellent advice! I appreciate the fast replies. Now that I've taken your approach of manipulating the controls purely from the testing tool, things are working much better.

                  I've approached it using QTP methods wired using EA _util via my custom add-in. I also have Selenium scipts from my dev team and the scLocators from them were also helpful. Those scripts also confirmed they were doing it with clicks in the testing tool - much as you suggested.

                  So far, I'm able to eliminate most of my custom addin JS and just use the QTP WebElement Click event. But, I like being able to use calls like "window.isc.AutoTest.locateCanvasFromDOMElement(domItem)" when I need to check out something from the SmartGWT controls.... 1 control down, 5 more to go!

                  Thanks again!
                  Do you mind sharing your finished code? I'm running into some of the same issues. Thanks

                  Comment

                  Working...
                  X