History | Log In     View a printable version of the current page.  
Issue Details (XML | Word | Printable)

Key: WTR-19
Type: Bug Bug
Status: In Progress In Progress
Priority: Major Major
Assignee: Angrez
Reporter: Bret Pettichord
Votes: 0
Watchers: 0
Operations

If you were logged in you would be able to see more operations.
Watir

xpath finds the wrong element

Created: 21/Apr/06 05:55 PM   Updated: 10/Jun/08 02:11 PM
Component/s: Xpath Support
Affects Version/s: 1.5.4
Fix Version/s: 1.6.1

Original Estimate: Unknown Remaining Estimate: Unknown Time Spent: Unknown
File Attachments: 1. HTML File list_matters.html (44 kb)
2. XML File test.xml (36 kb)



 Description  « Hide
Please see div2_xpath_test.rb (in unittests)

This is an xpath that finds the wrong element. You can use flash to see what is actually finding. The html is stripped down from an actual application page.

Note that i'm trying to convert some Selenium tests, that use xpath and the Selenium tests correctly find the correct element. I fear this may demonstrate a algorithmic flaw in our html to xml translation.

 All   Comments   Work Log   Change History      Sort Order:
Angrez - 24/Apr/06 01:50 AM
Hi Bret,

I have looked into in the issue. I think its the Text() function that is matching text of wrong div tag. I tried the following code:

ie.div(:xpath, "//div[contains(.,'Add') and @class='ButtonText']").flash
assert_equal('Add', ie.div(:xpath, "//div[contains(.,'Add') and @class='ButtonText']").text)

This code selects the correct 'div' element.

I'll again look into the XHTML that we generate from HTML document to see if we are generating it correctly.

Regards,
Angrez

Angrez - 24/Apr/06 09:13 AM
Hi Bret,

I am attaching both original HTML and the XHTML file that we get after the conversion. I have verified it twice that both are same and there is no re-ordering of the tags.

What I think is that there is no problem with conversion algorithm but the problem is something else. I'll investigate it more and see if Text() function of REXML 3.1.4 is working correctly or not.

Regards,
Angrez

Bret Pettichord - 28/Apr/06 04:10 PM
I've confirmed that the problem appears to be in REXML.

I instrumented the code thus:

def elements_by_xpath(xpath)
      puts 'original xpath: ', xpath
      doc = rexml_document_object
      modifiedXpath = ""
      selectedElements = Array.new
      doc.elements.each(xpath) do |element|
        modifiedXpath = element.xpath # element = a REXML element
        puts "modified xpath: #{modifiedXpath}"
        puts "text: #{element.text}"
        puts "class: #{element.attributes['class']}"
        temp = element_by_absolute_xpath(modifiedXpath) # temp = a DOM/COM element
        selectedElements << temp if temp != nil
      end

And then got this output:

original xpath:
//div[text()='Add' and @class='ButtonText']
modified xpath: /HTML/body/form/table/tbody/tr[2]/td/table/tbody/tr/td/table/tbody/tr[1]/td/div
text: Â
class:
modified xpath: /HTML/body/form/table/tbody/tr[2]/td/table/tbody/tr/td/table/tbody/tr[2]/td/div[1]/table/tbody/tr/td[2]/table/tbody/tr/td[1]/div/table/tbody/tr/td[2]/a/nobr/div
text: Add
class: ButtonText

Which shows that REXML is giving us an additional/spurious match. I'm unsure, however, quite how this incorrect match gets converted into the Open/Close/All div that we see in the test output...

1) Failure:
test_div(TC_Divs_XPath2) [C:/workspace/watir/unittests/div2_xpath_test.rb:15]:
<"Add"> expected but was
<"Open | Closed | All">.

Bret Pettichord - 28/Apr/06 05:52 PM
>I have looked into in the issue. I think its the Text() function that is matching text of wrong div tag. I tried the following code:
> ie.div(:xpath, "//div[contains(.,'Add') and @class='ButtonText']").flash
> assert_equal('Add', ie.div(:xpath, "//div[contains(.,'Add') and @class='ButtonText']").text)
>This code selects the correct 'div' element.

I have not been able to reproduce this. I modified the test to use contains instead of text and it fails, as detailed below.

I've committed this test in div2_xpath_test.rb

test_div_with_contains(TC_Divs_XPath2):
NoMethodError: undefined method `include?' for nil:NilClass
    C:/ruby/lib/ruby/site_ruby/1.8/rexml/functions.rb:142:in `contains'
    C:/ruby/lib/ruby/site_ruby/1.8/rexml/xpath_parser.rb:451:in `send'
    C:/ruby/lib/ruby/site_ruby/1.8/rexml/xpath_parser.rb:451:in `expr'
    C:/ruby/lib/ruby/site_ruby/1.8/rexml/xpath_parser.rb:438:in `each_with_index'
    C:/ruby/lib/ruby/site_ruby/1.8/rexml/xpath_parser.rb:438:in `each'
    C:/ruby/lib/ruby/site_ruby/1.8/rexml/xpath_parser.rb:438:in `each_with_index'
    C:/ruby/lib/ruby/site_ruby/1.8/rexml/xpath_parser.rb:438:in `expr'
    C:/ruby/lib/ruby/site_ruby/1.8/rexml/xpath_parser.rb:387:in `expr'
    C:/ruby/lib/ruby/site_ruby/1.8/rexml/xpath_parser.rb:283:in `expr'
    C:/ruby/lib/ruby/site_ruby/1.8/rexml/xpath_parser.rb:277:in `each_with_index'
    C:/ruby/lib/ruby/site_ruby/1.8/rexml/xpath_parser.rb:277:in `each'
    C:/ruby/lib/ruby/site_ruby/1.8/rexml/xpath_parser.rb:277:in `each_with_index'
    C:/ruby/lib/ruby/site_ruby/1.8/rexml/xpath_parser.rb:277:in `expr'
    C:/ruby/lib/ruby/site_ruby/1.8/rexml/xpath_parser.rb:488:in `d_o_s'
    C:/ruby/lib/ruby/site_ruby/1.8/rexml/xpath_parser.rb:485:in `each_index'
    C:/ruby/lib/ruby/site_ruby/1.8/rexml/xpath_parser.rb:485:in `d_o_s'
    C:/ruby/lib/ruby/site_ruby/1.8/rexml/xpath_parser.rb:490:in `d_o_s'
    C:/ruby/lib/ruby/site_ruby/1.8/rexml/xpath_parser.rb:485:in `each_index'
    C:/ruby/lib/ruby/site_ruby/1.8/rexml/xpath_parser.rb:485:in `d_o_s'
    C:/ruby/lib/ruby/site_ruby/1.8/rexml/xpath_parser.rb:490:in `d_o_s'
    C:/ruby/lib/ruby/site_ruby/1.8/rexml/xpath_parser.rb:485:in `each_index'
    C:/ruby/lib/ruby/site_ruby/1.8/rexml/xpath_parser.rb:485:in `d_o_s'
    C:/ruby/lib/ruby/site_ruby/1.8/rexml/xpath_parser.rb:490:in `d_o_s'
    C:/ruby/lib/ruby/site_ruby/1.8/rexml/xpath_parser.rb:485:in `each_index'
    C:/ruby/lib/ruby/site_ruby/1.8/rexml/xpath_parser.rb:485:in `d_o_s'
    C:/ruby/lib/ruby/site_ruby/1.8/rexml/xpath_parser.rb:490:in `d_o_s'
    C:/ruby/lib/ruby/site_ruby/1.8/rexml/xpath_parser.rb:485:in `each_index'
    C:/ruby/lib/ruby/site_ruby/1.8/rexml/xpath_parser.rb:485:in `d_o_s'
    C:/ruby/lib/ruby/site_ruby/1.8/rexml/xpath_parser.rb:490:in `d_o_s'
    C:/ruby/lib/ruby/site_ruby/1.8/rexml/xpath_parser.rb:485:in `each_index'
    C:/ruby/lib/ruby/site_ruby/1.8/rexml/xpath_parser.rb:485:in `d_o_s'
    C:/ruby/lib/ruby/site_ruby/1.8/rexml/xpath_parser.rb:490:in `d_o_s'
    C:/ruby/lib/ruby/site_ruby/1.8/rexml/xpath_parser.rb:485:in `each_index'
    C:/ruby/lib/ruby/site_ruby/1.8/rexml/xpath_parser.rb:485:in `d_o_s'
    C:/ruby/lib/ruby/site_ruby/1.8/rexml/xpath_parser.rb:490:in `d_o_s'
    C:/ruby/lib/ruby/site_ruby/1.8/rexml/xpath_parser.rb:485:in `each_index'
    C:/ruby/lib/ruby/site_ruby/1.8/rexml/xpath_parser.rb:485:in `d_o_s'
    C:/ruby/lib/ruby/site_ruby/1.8/rexml/xpath_parser.rb:490:in `d_o_s'
    C:/ruby/lib/ruby/site_ruby/1.8/rexml/xpath_parser.rb:485:in `each_index'
    C:/ruby/lib/ruby/site_ruby/1.8/rexml/xpath_parser.rb:485:in `d_o_s'
    C:/ruby/lib/ruby/site_ruby/1.8/rexml/xpath_parser.rb:490:in `d_o_s'
    C:/ruby/lib/ruby/site_ruby/1.8/rexml/xpath_parser.rb:485:in `each_index'
    C:/ruby/lib/ruby/site_ruby/1.8/rexml/xpath_parser.rb:485:in `d_o_s'
    C:/ruby/lib/ruby/site_ruby/1.8/rexml/xpath_parser.rb:490:in `d_o_s'
    C:/ruby/lib/ruby/site_ruby/1.8/rexml/xpath_parser.rb:485:in `each_index'
    C:/ruby/lib/ruby/site_ruby/1.8/rexml/xpath_parser.rb:485:in `d_o_s'
    C:/ruby/lib/ruby/site_ruby/1.8/rexml/xpath_parser.rb:490:in `d_o_s'
    C:/ruby/lib/ruby/site_ruby/1.8/rexml/xpath_parser.rb:485:in `each_index'
    C:/ruby/lib/ruby/site_ruby/1.8/rexml/xpath_parser.rb:485:in `d_o_s'
    C:/ruby/lib/ruby/site_ruby/1.8/rexml/xpath_parser.rb:490:in `d_o_s'
    C:/ruby/lib/ruby/site_ruby/1.8/rexml/xpath_parser.rb:485:in `each_index'
    C:/ruby/lib/ruby/site_ruby/1.8/rexml/xpath_parser.rb:485:in `d_o_s'
    C:/ruby/lib/ruby/site_ruby/1.8/rexml/xpath_parser.rb:490:in `d_o_s'
    C:/ruby/lib/ruby/site_ruby/1.8/rexml/xpath_parser.rb:485:in `each_index'
    C:/ruby/lib/ruby/site_ruby/1.8/rexml/xpath_parser.rb:485:in `d_o_s'
    C:/ruby/lib/ruby/site_ruby/1.8/rexml/xpath_parser.rb:490:in `d_o_s'
    C:/ruby/lib/ruby/site_ruby/1.8/rexml/xpath_parser.rb:485:in `each_index'
    C:/ruby/lib/ruby/site_ruby/1.8/rexml/xpath_parser.rb:485:in `d_o_s'
    C:/ruby/lib/ruby/site_ruby/1.8/rexml/xpath_parser.rb:490:in `d_o_s'
    C:/ruby/lib/ruby/site_ruby/1.8/rexml/xpath_parser.rb:485:in `each_index'
    C:/ruby/lib/ruby/site_ruby/1.8/rexml/xpath_parser.rb:485:in `d_o_s'
    C:/ruby/lib/ruby/site_ruby/1.8/rexml/xpath_parser.rb:490:in `d_o_s'
    C:/ruby/lib/ruby/site_ruby/1.8/rexml/xpath_parser.rb:485:in `each_index'
    C:/ruby/lib/ruby/site_ruby/1.8/rexml/xpath_parser.rb:485:in `d_o_s'
    C:/ruby/lib/ruby/site_ruby/1.8/rexml/xpath_parser.rb:476:in `descendant_or_self'
    C:/ruby/lib/ruby/site_ruby/1.8/rexml/xpath_parser.rb:315:in `expr'
    C:/ruby/lib/ruby/site_ruby/1.8/rexml/xpath_parser.rb:125:in `match'
    C:/ruby/lib/ruby/site_ruby/1.8/rexml/xpath_parser.rb:56:in `parse'
    C:/ruby/lib/ruby/site_ruby/1.8/rexml/xpath.rb:53:in `each'
    C:/ruby/lib/ruby/site_ruby/1.8/rexml/element.rb:939:in `each'
    C:/workspace/watir/unittests/../watir.rb:1957:in `elements_by_xpath'
    C:/workspace/watir/unittests/../watir.rb:1946:in `element_by_xpath'
    C:/workspace/watir/unittests/../watir.rb:2685:in `locate'
    C:/workspace/watir/unittests/../watir.rb:2154:in `assert_exists'
    C:/workspace/watir/unittests/../watir.rb:2222:in `text'
    C:/workspace/watir/unittests/div2_xpath_test.rb:19:in `test_div_with_contains'

Bret Pettichord - 28/Apr/06 06:37 PM
i have created failing rexml unit tests for this problem. they are committed to watir and have been submitted to rexml as ticket #61.

http://www.germane-software.com/projects/rexml/ticket/61

the test.xml file that is attached to this ticket demonstrates the whitespace problem in the Watir code that i had recently corrected. i presume angrez had not done an update from svn before creating it.

the failing tests i created for rexml were reproduced using both contains() and text().

/trunk/watir/unittests/other/rexml_bug.xml
  /trunk/watir/unittests/other/rexml_unit_test.rb

the watir bug has also been updated

/trunk/watir/unittests/other/xpath_bug.xml

bret

Angrez - 29/Apr/06 02:54 AM
Hi Bret,

> I have not been able to reproduce this. I modified the test to use contains instead of text and it fails, as detailed below.

> I' ve committed this test in div2_xpath_test.rb

Try installing REXML 3.1.4. I also got same errors when I tried the code with REXML 3.1.3. But when I installed REXML 3.1.4 errors were gone.

Regards,
Angrez


Bret Pettichord - 29/Apr/06 11:07 AM
I have REXML 3.1.4 installed and in fact had updated Watir to abort if a prior version of REXML is installed.

I just ran the tests and reproduced the same failures on my second development system (also with 3.1.4 installed).




Bret Pettichord - 06/Jun/06 03:23 PM
The REXML bug has been accepted and a fix is scheduled for 3.1.6, approx August.

Bret Pettichord - 12/Aug/06 10:45 PM
Rexml ticket is still open and Rexml 3.1.6. is unreleased. Nothing much we can do in the mean time...

Bret Pettichord - 28/Nov/06 09:41 AM
A fix has been made for REXML. This is scheduled for 3.1.7.