How do I get the HTML in an element using Capybara? - cucumber

I’m writing a cucumber test where I want to get the HTML in an element.
For example:
within 'table' do
# this works
find('//tr[2]//td[7]').text.should == "these are the comments"
# I want something like this (there is no "html" method)
find('//tr[2]//td[7]').html.should == "these are the <b>comments</b>"
end
Anyone know how to do this?

You can call HTML DOM innerHTML Property:
find('//tr[2]//td[7]')['innerHTML']
Should work for any browser or driver.
You can check all available properties on w3schools

This post is old, but I think I found a way if you still need this.
To access the Nokogiri node from the Capybara element (using Capybara 1.0.0beta1, Nokogiri 1.4.4) try this:
elem = find('//tr[2]//td[10]')
node = elem.native
#This will give you a Nokogiri XML element
node.children[1].attributes["href"].value.should == "these are the <b>comments</b>"
The last part may vary for you, but you should be able to find the HTML somewhere in that node variable

In my environment, find returns a Capybara::Element - that responds to the :native method as Eric Hu mentioned above, which returns a Selenium::WebDriver::Element (for me). Then :text gets the contents, so it could be as simple as:
results = find(:xpath, "//td[#id='#{cell_id}']")
contents = results.native.text
if you're looking for the contents of a table cell. There's no content, inner_html, inner_text, or node methods on a Capybara::Element. Assuming people aren't just making things up, perhaps you get something different back from find depending on what else you have loaded with Capybara.

Looks like you can do (node).native.inner_html to get the HTML content, for example with HTML like this:
<div><strong>Some</strong> HTML</div>
You could do the following:
find('div').native.inner_html
=> '<strong>Some</strong> HTML'

I ran into the same issue as Cyril Duchon-Doris, and per https://github.com/teampoltergeist/poltergeist/issues/629 the way to access the HTML of an Capybara::Poltergeist::Node is via the outerHTML property, e.g.:
find('//tr[2]//td[7]')['outerHTML']

Most of the other answers work only in Racktest (as they use Racktest-specific features).
If your driver supports javascript evaluation (like Selenium) you can use innerHTML :
html = page.evaluate_script("document.getElementById('my_id').innerHTML")

If you're using the Poltergeist driver, these methods will allow you to inspect what matches:
http://www.rubydoc.info/gems/poltergeist/1.5.1/Capybara/Poltergeist/Node
For example:
page.find('[name="form-field"]').native.value == 'something'

try calling find('//tr[2]//td[10]').node on it to get at the actual nokogiri object

Well, Capybara uses Nokogiri to parse, so this page might be appropriate:
http://nokogiri.org/Nokogiri/XML/Node.html
I believe content is the method you are looking for.

You could also switch to capybara-ui and do the following:
# define your widget, in this case in your role
class User < Capybara::UI::Role
widget :seventh_cell, [:xpath, '//tr[2]//td[7]']
end
# then in your tests
role = User.new
expect(role.widget(:seventh_cell).html).to eq(<h1>My html</h1>)

Related

Selenium - find element by link text

I am using selenium webdriver on Chrome; python 3 on Windows 10.
I want to scrape some reports from a database. I search with a company ID and a year, the results are a list of links formatted in a specific way: something like year_companyID_seeminglyRandomDateAndDoctype.extension, e.g. 2018_2330_20020713F04.pdf. I want to get all pdfs of a certain doctype. I can grab all links for a certain doctype using webdriver.find_elements_by_partial_link_text('F04') or all of that extension with '.pdf' instead of 'F04', but I cannot figure out a way to check for both at once. First I tried something like
links = webdriver.find_elements_by_partial_link_text('F04')
for l in links:
if l.find('.pdf') == -1:
continue
else:
#do some stuff
But unfortunately, the links are WebElements:
print(links[0])
>> <selenium.webdriver.remote.webelement.WebElement (session="78494f3527260607202e68f6d93668fe", element="0.8703868381417961-1")>
print(links[0].get_attribute('href'))
>> javascript:readfile2("F","2330","2015_2330_20160607F04.pdf")
so the conditional in the for loop above fails.
I see that I could probably access the necessary information in whatever that object is, but I would prefer to do the checks first when getting the links. Is there any way to check multiple conditions in the webdriver.find_elements_by_* methods?
You can try to use below code
links = [link.get_attribute('href') for link in webdriver.find_elements_by_partial_link_text('F04') if link.get_attribute('href').endswith('.pdf")')]
You can also try XPath as below
links = webdriver.find_elements_by_xpath('//a[contains(., "F04") and contains(#href, ".pdf")]')
Andersson's approach seems to work with a slight correction:
if link.get_attribute('href').endswith('.pdf')] rather than if link.get_attribute('href').endswith('.pdf")')], i.e. delete the ").

modx Decrement a TV to obtain 0

I need my [[+idx]] tv to start at 0 instead of 1 so I tried this:
[[+idx:decr]] or [[+idx:substract=1]] but it gives me -1 (minus one).
Does anyone know another way to obtain 0?
Thank you
Using this in chunk for getImageList works (at least for me):
[[+idx:decr]]
It gives: 0,1,2,3 ....
P.S. using modx revo 2.3.1
set your template variable default to 0 when you create the variable.
What are you trying to do, your question is vague at best.
UPDATE
ok - what I think will work for you is to write a snippet to do the math... where ever you call the [[+idx]] instead write a snippet
[[!FixIDX? &itemindex=`[[+idx]]`]]
then in your FixIDX snippet just do the math with php and return the corrected index. Though perhaps a custom output modifier would be the better way to go: http://rtfm.modx.com/display/revolution20/Input+and+Output+Filters+(Output+Modifiers)
Though looking at the docs, your code should certainly work - I see no reason for it not to.

How to repair this issue when i click on result link in modx ajaxSearch?

I used ajaxSearch on this site: http://www.rhemapress.pl/www_poradnia/ and when I type something, e.g: czwarta or wspomaganie then when i clicked on one of return links then it redirect me to this document but on end of this link is something like this:
&searched=wspomaganie&advsearch=oneword&highlight=ajaxSearch_highlight+ajaxSearch_highlight1 and i've got this error after I clicked.
MODx encountered the following error while attempting to parse the requested resource:
htmlentities() [function.htmlentities]: charset `ISO-8859-2' not supported, assuming iso-8859-1
/home/users/rhemapress/public_html/rhemapress/www_poradnia/manager/includes/document.parser.class.inc.php(790) : eval()'d code
Where is the problem? How can i do this correctly? Database is UTF8.
I think you need to replace the character set similar to how they do it here:
http://forums.modx.com/index.php?topic=17161.0
Find instances similar to this, specifically the "etomite_charset":
htmlentities($output,ENT_QUOTES,$modx->config['etomite_charset']);
Replace with something similar to this:
htmlentities($output, ENT_QUOTES);
However I don't know all the instance of where this would appear in the ajax search plugin.

Checking values with Cucumber and Watir

I've been trying to get started with Cucumber and Watir. I've done the installation and written/copied a simple 'feature'. However, I'm not getting anywhere with checking what's on a page.
This my feature:
Feature: Search Google
In order to make sure people can find my documentation
I want to check it is listed on the first page in Google
Scenario: Searching for JS.Class docs
Given I have opened "http://www.google.com/"
When I search for "JS.Class"
Then I should see a link to "http://jsclass.jcoglan.com/" with text "JS.Class v3.0"
My env.rb file looks like this
require 'watir'
require 'rspec'
And this is my search_steps.rb
#ie
Given /^I have opened "([^\"]*)"$/ do |url|
#ie = Watir::IE.new
#ie.goto(url)
end
When /^I search for "([^\"]*)"$/ do |arg1|
#ie.text_field(:name, "q").set(arg1)
#ie.button(:name, "btnG").click
end
Then /^I should see a link to "([^\"]*)" with text "([^\"]*)"$/ do |arg1, text|
puts arg1
# #ie.text.should include(arg1)
#ie.close
end
When I uncomment the line '#ie.text.should include(arg1)' I get this error thrown.
Then I should see a link to "http://jsclass.jcoglan.com/" with text "JS.Class v3.0" # features/step_definitions/search_steps.rb:13
true
undefined method `split' for ["http://jsclass.jcoglan.com/"]:Array (NoMethodError)
./features/step_definitions/search_steps.rb:17:in `/^I should see a link to "([^\"]*)" with text "([^\"]*)"$/'
features\search.feature:8:in `Then I should see a link to "http://jsclass.jcoglan.com/" with text "JS.Class v3.0"'
Failing Scenarios:
cucumber features\search.feature:5 # Scenario: Searching for JS.Class docs
Right now the Then function isn't doing its job. If I comment out the line then all it's really doing is writing out some text.
The gems I have include the following cucumber <1.1.9>, rspec <2.9.0>, watir<2.0.4> and watir-webdriver <0.5.3>
The version of ruby I have is: ruby 1.9.3p125.
I'm running this on Windows 7 Ultimate.
I'm wondering if I'm missing a gem or something. Reading the message implies that I'm calling a method it can't find but I've found quite a few pages on the web that use this method.
Any help, guidance or pointers in the right direction are gratefully welcomed.
The problem is that if you (manually) look at the text of the Google search results, you will noticed that there is no text "http://jsclass.jcoglan.com/". So, as expected, the test will fail.
To fix this, you can correct the call to the step by removing the 'http://':
Then I should see a link to "jsclass.jcoglan.com/" with text "JS.Class v3.0"
That said, it would be more robust if you actually make check for the link using the following code. Checking that the text is somewhere on the page can lead to false positives (see the latest post on WatirMelon)
#ie.link(:url => arg1, :text => text).exists?.should be true

serve_file for any file object

In cherrypy.lib.static.py there is a method:
serve_file(path, content_type=None, disposition=None, name=None)
where the argument "path" must be a real file (absolute path). Is there something similar to serve any Python file object?
From studying http://www.cherrypy.org/browser/trunk/cherrypy/lib/static.py I'd have to say, no: the serve_file function is "monolithic", and does its own bodyfile = open(path, 'rb'), nor does there seem to be any alternative way. Pity, as it would be easy to refactor the function and add another e.g. serve_open_file to cover your case, having both delegate to an internal function for the "hard" logic such as multipart/byteranges serving. May be worth your while to open a feature request ("enhancement ticket") on cherrypy.org -- may not be a killer feature but I can see use cases, and implementing it wouldn't be hard for the cherrypy people (visit their site and follow the instructions on the page to "log in" to it).
As long as your file or file-like object is iterable, just return it from your handler function instead of a string.
Update:
To serve it as a download, set the Content-Type and Content-Disposition headers like so:
cherrypy.response.headers["Content-Type"] = "application/x-download"
cd = 'attachment; filename="%s"' % name
cherrypy.response.headers["Content-Disposition"] = cd
Or, use the serve_fileobj function in recent versions of cherrypy/lib/static.py, which does this for you and more.
Taking a new look at http://www.cherrypy.org/browser/trunk/cherrypy/lib/static.py, it looks like serve_fileobj does exactly what you want.
Edit: I've tried this now, and it only renders the file contents to the screen, rather than allowing the file to be downloaded.

Resources