views:

290

answers:

1

Hello,

I am a newbie in WATIR. The problem I am facing is - The application I am testing has thumbnails (like Windows icons) placed on the page and I need to double click it. On doing that, an custom popup (ajax popup implemented in javascript) will open. The fire_event("ondblclick") is not working for me. I also tried 'click' twice but that too is not helping. Is there any other way of handling this? Your help is highly appreciated.

Added 6 July 2010:

I solved it but I have another query now.

Below was the HTML for which I was able to solve using "@ie.div(:class,'GridElementInlineIE').fire_event('ondblclick') "


<div class="gridViewItem" style='display: inline-table;' ondblclick='openAsset("634119577077187500", "", "LIBRARY_ASSETS_TAB", "1", "A111");'
        id='GridComponent634119577077187500'>
        <table style="display: inline-table;" class="gridViewItemTable" cellpadding="0" cellspacing="0"
            onclick="highlightAsset(this, event)" projectid="" dmguid="634119577077187500"
            id="_thumb_634119577077187500" objectclass="VIDEO">
            <tr>
                <td style="padding: 10px 10px 0px 7px">
                    <img class="assetListGridImage draggableThumbnail" id="thumb_634119577077187500"
                        title="A111" alt="A111"
                        src="/images/wait.gif" dmguid="634119577077187500" projectid=""
                        objectclass="VIDEO" _onclick="highlightAsset(this, event)" />
                </td>
            </tr>
            <tr>
                <td style="padding: 0px 0px 0px 7px">

                    A111
                </td>
            </tr>
            <tr>
                <td style="padding: 0px 0px 5px 7px; min-height: 33px; max-height: 33px; height: 33px;">
                    <img alt='Not starred' name='IMAGE634119577077187500' title='Star this asset' src='/Images/star_off.png' onclick='toggleStar(event, this, "634119577077187500")' class='starGrid' />
                    <img alt='video' title='video' src='/Images/asset_type/VIDEO.png'/>
                    <img src='/images/shared.png'  title ='Shared' alt='Shared' />
                </td>

            </tr>
        </table>
    </div>

Now I need to double click on this item (code below). But even though the element is being identified (highlighted with a yellow), the double click is not working. I am trying "@ie.div(:class,'gridViewItem').fire_event('ondblclick')". I've also tried the while loops and click-twice options to no effect. I'm using Watir 1.6 with Ruby186-27_rc2.

           div class="GridElementInline">
                <table class="GridElementInline" style="border: solid 2px #1e606e;min-height:134px;height:134px;max-height: 134px" onclick="highlightAsset(this, event)"
                                                projectid='' folderid="2383" id="_tblBinlist2383" title = "today">
                    <tr>
                        <td style="padding: 10px 10px 0px 7px;">
                            <table id='tblBinlist2383' folderid='2383' projectId='' _onclick='highlightAsset(this, event)' ondblclick='showBinDetails("2383", "")' class='binThumbnail GridElementInline' cellpadding='0' cellspacing='0'><tr><td><img class='fourGridViewImage' src='http://stream.....' /></td><td><img class='fourGridViewImage' src='http://stream.....' /></td></tr><tr><td><img class='fourGridViewImage' src='http://stream.....' /></td><td><img class='fourGridViewImage' src='http://stream.....' /></td></tr></table>
                        </td>
                    </tr>
                <tr>
                <td colspan="2" align="center" style="padding: 10px 10px 0px 7px; font-size: 9px;white-space: nowrap;">
                <div align="left" title="today">
                    today
                </div>
                </td>
                </tr>
                </table>
            </div>
A: 

Here's a quick and slightly dirty workaround in case you get truly stuck with this. This ensures automatic relative hardware clicking to save the problems that the click event has (and traditionally, it has them in some corner cases).

Stick this in a file called, say, "mouseControl.rb" then link to it from your main file with require 'mouseControl'... or however you wish to go about it. It's been a while since I used it but I'm sure you can hack a double click out of it. I haven't included said hack because I happen to know this file works (or at least worked). You will need to require 'win32ole'. When you've got it set up you should be able to simply say things like @brower.button(:text, "boo").left_click to do a manual top-layer hardware click.

Should tide you over until you can get a better answer.

require 'watir'

module Watir
  class Element
    def top_edge
      assert_exists
      assert_enabled
      ole_object.getBoundingClientRect.top.to_i
    end

    def top_edge_absolute
      top_edge + page_container.document.parentWindow.screenTop.to_i
    end

    def left_edge
      assert_exists
      assert_enabled
      ole_object.getBoundingClientRect.left.to_i
    end

    def left_edge_absolute
      left_edge + page_container.document.parentWindow.screenLeft.to_i
    end

    def left_click
      x = left_edge_absolute + 1
      y = top_edge_absolute + 1
      #puts "x: #{x}, y: #{y}"
      WindowsInput.move_mouse(x, y)
      WindowsInput.left_click
    end

    def right_click
      x = left_edge_absolute
      y = top_edge_absolute
      #puts "x: #{x}, y: #{y}"
      WindowsInput.move_mouse(x, y)
      WindowsInput.right_click
    end
  end
end 


module WindowsInput
  # Windows API functions
  SetCursorPos = Win32API.new('user32','SetCursorPos', 'II', 'I')
  SendInput = Win32API.new('user32','SendInput', 'IPI', 'I') 
  # Windows API constants
  INPUT_MOUSE = 0 
  MOUSEEVENTF_LEFTDOWN = 0x0002 
  MOUSEEVENTF_LEFTUP = 0x0004 
  MOUSEEVENTF_RIGHTDOWN = 0x0008 
  MOUSEEVENTF_RIGHTUP = 0x0010 

  module_function

  def send_input(inputs) 
    n = inputs.size 
    ptr = inputs.collect {|i| i.to_s}.join # flatten arrays into single string 
    SendInput.call(n, ptr, inputs[0].size) 
  end

  def create_mouse_input(mouse_flag) 
    mi = Array.new(7, 0) 
    mi[0] = INPUT_MOUSE 
    mi[4] = mouse_flag 
    mi.pack('LLLLLLL') # Pack array into a binary sequence usable to SendInput 
  end 

  def move_mouse(x, y)
    SetCursorPos.call(x, y)
  end

  def left_click
    leftdown = create_mouse_input(MOUSEEVENTF_LEFTDOWN) 
    leftup = create_mouse_input(MOUSEEVENTF_LEFTUP) 
    send_input( [leftdown, leftup] )
  end

  def right_click
    rightdown = create_mouse_input(MOUSEEVENTF_RIGHTDOWN) 
    rightup = create_mouse_input(MOUSEEVENTF_RIGHTUP) 
    send_input( [rightdown, rightup] )
  end
end
kinofrost
Thank you, kinofrost, but we have already tried with this one without effect.
Namratha
So you can identify it as an element to click on, but a hardware double click has no effect on it? I mean writing a new method, def double_click, containg two lines of "left_click", and calling it direct from the identified element has no effect? If not then I'm completely stuck. I could suggest trying the AutoIT workaround, but to be honest if hardware clicks on an IDd element aren't working you may need to find another way to interact with it. If I could see the code you were writing to click it it may be of some help. Presumably you're testing on an IE window on a local machine...
kinofrost