Hello I've been struggling with a should be simple select with capybara. This is what I'm after on my page :
<a title="Activity" class="" href="/changes">Activity <span class="badge">1</span></a>
I need to assert that there is a span.badge with value 1 inside activity a tag.
Before I posted this, printed the page contents and did a save_and_open_page and this content is there.
This is what I tried (which seemed most promising cant even find a tag) :
find(:xpath, "//a[contains(.,'Activity')]")
find(:xpath, "//a[contains(#title, \"Activity\")]")
find(:xpath, "//a[#title='Activity']")
find(:xpath, "//a", :text => /reActivity /i)
And so many other things not worth mentioning, how would you do this?
Question update:
I forgot to mention that this html is actually hidden initially on the page as it is part of a sub menu. So adding Capybara.ignore_hidden_elements = false works but it kind of sux to add this global config to your test, any other ideas?
If I'm understanding what you're trying to do you can use a css selector for this, which will be easier to read than XPath
find('a[title=Activity] span.badge', text: '1', visible: :all)
Assuming the elements are visible on the page that should find what you want. To assert on that if using RSpec something like the following with work
expect(page).to have_css('a[title=Activity] span.badge', text: '1', visible: :all)
if i understood correctly
//a[#title="Activity" and span[#class="badge" and . = 1]]
Related
Homemade NavBar. environment contains lists with the dropdown elements defined like this:
{
title: 'Overview', isDropped: false, Links: [
{linkTitle: 'What is Hunter', linkRoute: '/whatishunter'},
{linkTitle: 'What is a Hard Problem', linkRoute: '/hardproblem'},
{linkTitle: 'Real World Applications', linkRoute: '/realapps'},
{linkTitle: 'Using Hunter', linkRoute: '/usingHunter'}
]
},
The navbar html loops (ngFor) for each dropdown in that section of the navbar; added leftdropdown is dropped to show what's happening:
<div class="positionLeft" [ngStyle]="{'z-index': '2', 'height': '50px'}">
<div *ngFor="let leftdropdown of barContents.leftMenus">
<app-navdropdown [title]="[leftdropdown.title]" [isDropped]="[leftdropdown.isDropped]"
[links]="[leftdropdown.links]"></app-navdropdown>
added leftdropdown isdropped = {{leftdropdown.isDropped}}
</div>
The "leftdropdown" elements are from the environment list above. The component.ts is:
And it's trivial HTML is (with extra diagnostic text):
So when the application runs we see the output html as:
Note the debug console here:
And just to be sure, I can manually change isDropped to true and the "if block" is displayed.
The obvious error is that *ngIf is inverting the isDropped expression ????
Any clues as to what must be a misunderstanding or simple syntax error?
Thanks for your time and advice.
Chuck (Yogi)
Thanks for the various comments; I finally realized that MY confusion about square brackets was regarding the left or right of the expression. Using (or not using) square brackets on the left changes how the right side is evaluated. (I thought they needed to be applied to the right side - WRONG.)
After carefully (and repeatedly) reviewing the property binding documentation in angular.io, the above became clear to me.
Thanks to everyone who added notes.
How would I get all 10 comments located in this page with a loop or a Puppeteer function https://www.tripadvisor.com/Restaurant_Review-g294308-d3937445-Reviews-Maki-Quito_Pichincha_Province.html using innerText property?
The only solution I have come up with is getting the outerHTML of the whole container of comments and then try to substring to get all the comments, but that is not optimal and I think its a more difficult approach. Maybe there is an easier solution in Puppeteer I cant find?
I am doing this for educational purposes. The comments are in class="partial_entry" and I want to get the innerText of a Dynamic Html tag (I want all 10), like the ones you see here:
If I where to open the div that contains <div class="review-container" data-reviewid="606551292" data-collapsed="true" data-deferred="false"><!--trkN:3-->, I would get another with id="review_582693262". Getting to the point, If I get to a <div> that has class="partial_entry" this would be where my comment is located. I have tried a few things but I get null, because it is not found since the parent <div> for each comment has a unique id like id="review_xxxxxxxxx".
Its kind of difficult since the review id is autogenerated like id="review_xxxxxxxxx" and cant iterate with a loop copying the CSS path since I dont have a static parent .
Why not just select those elements which have partial_entry class? This works:
let comments = await page.evaluate(() =>
[...document.querySelectorAll(".partial_entry")].map(item => item.textContent)
);
I have this function and i am not able to click on all of the magnifying glasses from a page. I have tried until now, by using different alternatives. What is commented, is what i tried until now.
def lupa():
elements = browser.find_elements_by_css_selector("a[onclick='return Go(event, 2)'] > img[title='Details']")
for element in elements:
#element.click()
element.send_keys(Keys.SPACE)
time.sleep(1)
Please see below how looks the HTML code.
<a href="#" onclick="return Go(event, 2)">
<img title="Details" src="/common/images/Detail.gif">
</a>
This are the old XPATHs i used in order to click on the image.
#browser.find_element_by_xpath(".//*[#id='resultsTable']/tbody/tr[17]/td[11]/a[2]/img").click()
#lupa = browser.find_element(By.XPATH("//img[#src='/common/images/Detail.gif']"))
#lupa = browser.find_element(By.cssSelector("a[src='/common/images/Detail.gif']"))
#lupe = browser.find_elements_by_css_selector("a[src='/common/images/Detail.gif']"))
#lupa=browser.find_element_by_link_text("Details").click()
#lupa= browser.find_element_by_id("Details").click()
#elements = browser.find_elements_by_css_selector("a[src='/common/images/Detail.gif']"))
Thank you for your answer!
Cohen
Most of the locators you tried aren't valid. You probably should spend some time learning about the different locator types and how they work.
Given the HTML, the CSS selector below should find the IMG tag(s) you want.
img[title='Details']
Another thing, you are not using implicit wait correctly. It's set once for the life of the driver. Calling it over and over does nothing. You don't want to use implicit wait, use an explicit wait instead. Look at some tutorials for WebDriverWait.
EDIT: Clicking the IMG tag should work just find since it's surrounded by the desired A tag. But... if you need to click the A tag specifically, you should be able to use the locators below.
More specific CSS selector
a[onclick='return Go(event, 2)'] > img[title='Details']
XPath
//a[#onclick='return Go(event, 2)'][./img[title='Details']]
Hi I am trying to access the DIV element using watir but I am unable to do that,I have tried in different ways but couldn't access it,may be I think it need to be access through some parent element can anyone help me out?
My system Configurations
IE-8
Windows 7
I tried with the below command
#ie.div(:text,'COMPOSE').click
the command gets execute with no errors but no action is performed on the UI
The best solution appears to be switching to Watir-Webdriver. With Watir-Webdriver, #ie.div(:text,'COMPOSE').click will work as expected.
Assuming that is not an option, there are a couple of reasons why that same command does not work with Watir(-Classic) v1.6.7:
The first problem is that #ie.div(:text,'COMPOSE').click will find the first div that contains this text. This would be one of the ancestors of the div you want. As a result, Watir will send the click event against the wrong element.
The second problem is that the div is not responding to the onclick event fired by Watir. I am not sure why this problem exists.
To solve the first problem, you will need to be more specific when locating the div. In this case, the "role" attribute can be used since none of the ancestor elements have this attribute. Watir-Classic does not support using the role attribute as a locator. As a result, you will need to create a custom locator using an element collection and the find method:
#ie.divs.find{ |div| div.attribute_value('role') == 'button' && div.text == 'COMPOSE' }
To solve the second problem, it turns out that double clicking does work. While newer versions of Watir-Classic have a double_click method implemented, it does not exist in 1.6.7. You can replicate the method by calling the fire_event method:
.fire_event('ondblclick')
Putting it all together, the following will click the compose button:
#ie.divs.find{ |div| div.attribute_value('role') == 'button' && div.text == 'COMPOSE' }.fire_event('ondblclick')
There may be more than one element on the page with the text 'COMPOSE', some may be hidden. Try:
#ie.divs(:text,'COMPOSE').size
That is divs with an s.
Then you can try something like the following and see if you get a change in the UI:
#ie.divs(:text,'COMPOSE').each { |b| b.fire_event('click') }
I remember that fire_event works better, but would recommend consulting the docs for the difference between .click and fire_event.
i will be short.
As far as i know watir library provides two methods for getting html elements.
Almost for each element (div, button, table, li, etc) watir provides two methods:
. One is the 'singular' method which gets only one specific element. For example:
watir_instance.div(:id,'my_div_id')
watir_instance.link(:href,'my_link_href')
watir_instance.button(:class =>'my_button_class', :index => 4)
These methods will only retrieve A SINGLE ELEMENT. Thats ok...
. The second is the 'plural' method that will retrieve ALL the elements of the watir instance
watir_instance.divs
watir_instance.links
watir_instance.buttons
But as far as i know watir doesn't provide a method to get more than one element giving certain conditions.
For example... If i want to flash all the links with id:my_link_id it would be very easy to do something like this:
watir_instance.divs(:id, 'my_link_id').each do |link|
link.flash
end
With hpricot this task is very easy... but if your aim is not to parse i couldn't find a Watir Method that does what i want.
Hope you can understand me...
Cheers, Juan!!
Juan,
your script has several problems:
You say you want to flash all links, but then you use watir_instance.divs. It should be watir_instance.links
you pass arguments to divs method: watir_instance.divs(:id, 'my_link_id'). It should be just watir_instance.divs
Your example is also strange:
i want to flash all the links with
id:my_link_id
As far as I know, id should be unique at the page.
So, here are different examples:
1) Flash all links on this page:
require "watir"
b = Watir::IE.start "http://stackoverflow.com/questions/1434697"
b.links.each do |link|
link.flash
end
2) Flash all links on this page that have questions in URL (bonus: scroll the page so the link that is flashed is visible):
require "watir"
b = Watir::IE.start "http://stackoverflow.com/questions/1434697"
b.links.each do |link|
if link.href =~ /questions/
link.document.scrollintoview
link.flash
end
end