Result of xpath is object text error, how do i get around this in Ruby on a site built around hiding everything?

377 views Asked by At

My company uses ways to hide most data on their website and i'm tying to create a driver that will scan closed jobs to populate an array to create new jobs thus requiring no user input / database access for users.

I did research and it seems this can't be done the way i'm doing it:

# Scan page and place 4 different Users into an array
String name = [nil, nil, nil, nil]
String compare_name = nil
c = 0
tr = 1
while c < 4
  String compare_name = driver.find_element(:xpath, '//*
[@id="job_list"]/tbody/tr['+tr.to_s+']/td[2]/span[1]/a/span/text()[2]').gets
  if compare_name != name[c]
   name[c] = compare_name
       c = +1
       tr = +1
  else if compare_name == name[c]
       tr = +1
     end
  end
end

Also i am a newb learning as i go, so this might not be optimal or whatever just how i've learned to do what i want.

Now the website code for the item i want on the screen:

<span ng-if="job.customer.company_name != null &amp;&amp; 
job.customer.company_name != ''" class="pointer capitalize ng-scope" data-
toggle="tooltip" data-placement="top" title="" data-original-title="406-962-
5835">
<a href="/#/edit_customer/903519"class="capitalize notranslate">
    <span class="ng-binding">Name Stuff<br>
     <!-- ngIf: ::job.customer.is_cip_user --
<i ng-if="::job.customer.is_cip_user" class="fa fa-user-circle-o ng-scope">
::before == $0
</i>
> Diago Stein</span>
       </a>
</span>

Xpath can find the Diago Stein area, but because of it being a text object it doesn't work. Now to note something all the class titles, button names, etc are all the same with everything else on the page. They always do that which makes it even harder to scan because those same things are likely elsewhere that might not have anything to do with this area of the site.

Is there any way to grab this text without knowing what might be in the text area based on the HTML? Note "Name Stuff" is the name of a company i hid it with this generic one for privacy.

Thanks for any ideas or suggestions and help.

EDIT: Clarification, i will NOT know the name of the company or the user name (in this case Diago Stein) the entire purpose of this part of the code is to populate an array with the customers name from this table on the closed page.

1

There are 1 answers

9
JeffC On

You can back your XPath up one level to

//*[@id="job_list"]/tbody/tr[' + tr.to_s + ']/td[2]/span[1]/a/span

then grab the innerText. The SPAN is

<span class="ng-binding">Name Stuff<br>
  <!-- ngIf: ::job.customer.is_cip_user --
    <i ng-if="::job.customer.is_cip_user" class="fa fa-user-circle-o ng-scope">
      ::before == $0
    </i>
  > Diago Stein</span>

The problem is that this HTML has some conditionals in it which makes it hard to read, hard to figure out what's actually there. If we strip out the conditional, we are left with

<span class="ng-binding">Name Stuff<br>Diago Stein</span>

If we take the innerText of this, we get

Name Stuff
Diago Stein

What this does is you can split the string by a carriage return and part 0 is the 'Name Stuff' and part 1 is 'Diago Stein'. So you use your locator to find the SPAN, get innerText, split it by a carriage return, and then take the second part and you have your desired string.

This code isn't tested but it should be something like

name = driver.find_element(:xpath => "//*[@id="job_list"]/tbody/tr[' + tr.to_s + ']/td[2]/span[1]/a/span").get_text.split("\n")[1]