Zeljko Filipin wrote:
> ie.radio(:id, "id").readonly?
>
> On 6/1/06, *Adrian Rutter* <[EMAIL PROTECTED] 
> <mailto:[EMAIL PROTECTED]>> wrote:
>
>
>     Hi,
>
>     I have an HTML field that once saved becomes read-only
>     [readonly="true"].
>     Apart from doing a regex on the source how can I determine this
>     property?
>
>     Cheers
>
>     Aidy
>
I've just encountered a situation where this doesn't work, and written a 
fix for it, though I'm not sure where this fix would best be integrated.

The problem is that while an input element may NOT be read only, a 
containing element like a table cell, table row or div may have their 
visibility turned off, which prevents Watir from setting the focus on 
the input element and effectively makes the input element read only even 
though the readonly attribute is false:

irb(main):014:0> ie.text_field(:id, 'Detail_Date').readonly?
=> false
irb(main):015:0> ie.text_field(:id, 'Detail_Date').set('01/01/2000')
WIN32OLERuntimeError: focus
    OLE error code:800A083E in htmlfile
      Can't move focus to the control because it is invisible, not 
enabled, or of a type that does not accept the focus.
    HRESULT error code:0x80020009
      Exception occurred.
        from 
c:/ruby/lib/ruby/gems/1.8/gems/watir-1.5.0.1010/./watir.rb:3871:in 
`method_missing'
        from 
c:/ruby/lib/ruby/gems/1.8/gems/watir-1.5.0.1010/./watir.rb:3871:in `set'
        from (irb):15

In this case, a TR element a few levels higher has a style of 
"visibility: hidden; display: none" so the control is invisible and thus 
read only.

I see a few solutions.  The first would be to try to update the input 
element and then rescue the WIN32OLERuntimeError exception.  I'm not 
particularly fond of this, especially since the exception isn't an 
exception specific to this problem.  Another option is to iterate up the 
DOM elements checking every element to make sure that is is visible.  
This could be done in
Element#readonly?, but then we wouldn't be able to see the value of the 
actual readonly attribute.  I chose to implement another method which I 
called "writable?" which first checks that the element exists, is 
enabled and not readonly and then moves up the DOM tree and reports 
false if any element is not visible (visibility != 'hidden' and display 
!= 'none').

I've tested this and while it can be slow if the input element is deeply 
embedded it *does* seem to be accurate:

irb(main):016:0> ie.text_field(:id, 'Detail_Date').writable?
=> false
irb(main):017:0> ie.text_field(:id, 'Detail_DOB').writable?
=> true

You can try this by adding the following method in your Watir script or 
by adding just the writable? definition inside class Element in 
Watir.rb.  I can add this to trunk once I get some tests written to test 
it if we decide this is the way to go.  Does anyone have a cleaner or 
faster way to do this?

module Watir
  class Element
    # Determine if we can write to a DOM element.
    # If any parent element isn't visible then we cannot write to the
    # element.  The only realiable way to determine this is to iterate
    # up the DOM elemint tree checking every element to make sure it's
    # visible.
    def writable?
      assert_exists
      # First make sure the element itself is writable
      begin
        assert_enabled
        assert_not_readonly
      rescue Watir::Exception::ObjectDisabledException, 
Watir::Exception::ObjectReadOnlyException
        return false
      end
      return false if ! document.iscontentEditable
     
      # Now iterate up the DOM element tree and return false if any
      # parent element isn't visible or is disabled.
      object = document
      while object
        begin
          if object.style.invoke('visibility') =~ /^hidden$/i
            return false
          end
          if object.style.invoke('display') =~ /^none$/i
            return false
          end
          if object.invoke('isDisabled')
            return false
          end
        rescue WIN32OLERuntimeError
        end
        object += '.parentElement'
      end
      true
    end
  end
end



_______________________________________________
Wtr-general mailing list
Wtr-general@rubyforge.org
http://rubyforge.org/mailman/listinfo/wtr-general

Reply via email to