Capybara, selecting 1st option from dropdown? - selenium

I've done a search and most of the related google results have returned just in general selecting an element from a dropdown. However the ID's in this case for the elements in the dropdown are dynamically generated unfortunately.
This is for a base test case, so I basically just need to select for example the first one. The text is also the same for the elements in the dropdown (not sure if that helps).
Is there such an example of this?
Im using cucumber with caybara(using selenium driver) integration

You can find the first option element and then use the select_option method to select it.
For example, if the select list has an id "select_id", you can do:
first('#select_id option').select_option
As #TomWalpole mentions, this will not wait for the element to appear. It would be safer to do one of the following:
first('#select_id option', minimum: 1).select_option
or
find('#select_id option:first-of-type').select_option

Alternatively you can get the first element text then select it by select function:
first_element = find("#id_of_dropdown > option:nth-child(1)").text
select(first_element, :from => "id_of_dropdown")

After two days of searching and reading, this article was amongst one of a few that was helpful. Hopefully, this can help someone else!
I created a few methods like so, excuse the naming..I changed it.
def some_dropdown(id, text)
dropdown = find(id).click
dropdown.first('option', text: text).select_option
end
def select_form
within 'content#id' do
some_dropdown('#id', text)
click_link_or_button 'Submit'
end
end
I also referenced this.

I've tried to select an option from a modal dropdown. After trying all listed methods, and many other from other threads - I totally gave up and instead of using clicks or select_option just used keyboard keys
find(:select, "funding").send_keys :enter, :down, :enter
In case it still complains - try:
find(:select, "funding", visible: false).send_keys :enter, :down, :enter
Worked like a charm, selecting first option from a dropdown.

Related

selenium python how to find and click element that change everytime

im trying to find an element with dinamic values , for example <span class="ms-Button-label label-175" id="id__177">Save</span> in inspect element, the id and class values tend to change for every refresh, how can i in this case find the element in selenium? i tried troguht xpath but seems doesnt work because can not find the path, i was thinking to find "Save" world torught always find by xpath but actually i dont know if im doing well : driver.find_element_by_xpath(//span(#.... but then? how can insert element if it changes everytime? thanks!
Something like this may work:
driver.find_element_by_xpath('//span[text()="Save"]')
But this will fail, if there is more than one button with text "Save" on the page.
In that case you may try to find some specific outer element (div, form, etc.) which does not change and contains the button. Then find the button inside of it.
With few requests with driver:
specific_div = driver.find_element_by_id("my_specific_div")
button = specific_div.find_element_by_tag_name("span") # e.g. there is only one span in that div
Or with more specific xpath:
button = driver.find_element_by_xpath('//div[#class="some-specific-class"]/span[text()="Save"]')
If needed, search for more nested elements before the button, so you can get more narrow search field.
More examples in the docs.

I.click()-selector in CodeceptJS - how to find first button with specific innerHTML

I have various buttons and several buttons with the same name "Start". I need to click on the first found button with this name (innerHTML).
With jQuery this works with :
$('button:contains(Start):first').click()
How does it work with I.click()-Selector in CodeceptJS? I can't find the right syntax and always getting:
"invalid selector: An invalid or illegal selector was specified"
Here is the API for this function: https://github.com/Codeception/CodeceptJS/blob/master/docs/webapi/click.mustache
The only working solution I found is:
I.click('//button[1]');
But this solution is confusing, because you need to know the exactly number in the order of this element - and I have a lot of buttons with different names. Also this not allows me to search by innerHTML such as "Start".
You could use the I.executeScript like this:
I.executeScript("var elements = document.getElementsByName('Start');elements[0].click();"); or
I.executeScript("var elements =
document.querySelector(\"button[name*='Start']\");elements[0].click();");
You need using XPath for that
//button[1][contains(text(), 'Start')]
locate("//button[contains(text(), 'Start')]").first()
or
locate("//button[contains(text(), 'Start')]").at(1)
Works fine.

Using an OR condition in Xpath to identify the same element

I have this logic which gets the current page's title first clicks on next button, fetches the title again and if both the titles are the same, meaning navigation has not moved to the next page, it clicks on Next again.
However, my problem is that the title element's Xpath differs - the same title element has two Xpaths. One is some pages the other in some other pages.
It is either this,
(.//span[#class='g-title'])[2]
OR
.//span[#class='g-title']
So, how can I handle this?
If the element has two xpath, then you can write two xpaths like below
xpath1 | xpath2
Eg: //input[#name="username"] | //input[#id="wm_login-username"]
It will choose any one xpath
You can use or operator like
(.//span[#class='g-title'])[2] or .//span[#class='g-title']
For more details : Two conditions using OR in XPATH
You can use or, like below:
//tr[#class='alternateRow' or #class='itemRow']
I had an interesting insight I had using this method. In my python code I was clicking a cart button and the or "|" ONLY works with separate xpath statements like so ...
WebDriverWait(webdriver,20).until(EC.visibility_of_element_located((By.XPATH,"//*[#class='buttoncount-1'] | //button[contains(text(), 'Add to Cart')]")))
or
btn = webdriver.find_element_by_xpath("//*[#class='buttoncount-1'] | //button[contains(text(), 'Add to Cart')]")
I found that "or" ONLY works when they share the same bracket []
WebDriverWait(driver,10).until(EC.element_to_be_clickable((By.XPATH,"//button[contains(text(), 'Add to Cart') or contains(text(),'Buy')]"))).click()
And since you're here. If you're curious about "and" statements this worked for me...
WebDriverWait(driver,10).until(EC.element_to_be_clickable((By.XPATH,"//button[contains(text(), 'Continue To Order Rev')][#data-attr='continueToOrderReviewBtn']"))).click()
Simply pairing two separate statements was sufficient. No "and" necessary.
Note: This was all in python. I do not know how this will transfer over to java. Hope this was somewhat useful. It took me a few migraines to narrow this down.

The best Xpath option for the below example

Please let me know the best xpath for the below HTML, the button id's are dynamically populated. Hence I tried using the starts-with function as below
driver.findElement(By.xpath("*//button[starts-with(#id, 'j_idt')]")).click();
but, how to achieve if we have two buttons in the same page as per the attached screenshot.
There are multiple ways to find the button. One of the options is to rely on the text inside, e.g. for Login:
//button[span = 'Login']
Then, you can add other checks, e.g. check if it is of type submit:
//button[#type = 'submit' and span = 'Login']

selenium (phpunit) click on drop down link

I want be able click on link from drop down using selenium with phpunit. I don't have any idea how make it happens, can anyone show me example or relevant tutorial, post or anything that can help me figure out.
when I try click on the element without put mouse over the drop down I got this error:
Element is not currently visible and so may not be interact with command ....
Thanks.
EDIT:
when I said "drop down" I don't mean regular select. it more like popup
you can see the example here:
http://investing.com
look how they build the menu I want be able click on 'Technical' -> 'Fibonacci Calculator' for example.
Check this post out:
Selenium: How to select an option from a select menu?
You can find more info about this here
select(selectLocator, optionLocator)
Arguments:
selectLocator - an element locator identifying a drop-down menu
optionLocator - an option locator (a label by default)
Select an option from a drop-down using an option locator.
Option locators provide different ways of specifying options of an HTML Select element (e.g. for selecting a specific option, or for asserting that the selected option satisfies a specification). There are several forms of Select Option Locator.
label=labelPattern: matches options based on their labels, i.e. the visible text. (This is the default.)
label=regexp:^[Oo]ther
value=valuePattern: matches options based on their values.
value=other
id=id: matches options based on their ids.
id=option1
index=index: matches an option based on its index (offset from zero).
index=2
If no option locator prefix is provided, the default behaviour is to match on label.
Credits go to Dave Hunt
What I use:
$search13 = $this->webDriver->findElement(WebDriverBy::id('id_of_dropdown_field'));
$search13->click(); // Clicking on the dropdownfield
$this->webDriver->getKeyboard()->pressKey('ARROW_DOWN'); // Will go down in your dropdown selection )
sleep(1);
$this->webDriver->getKeyboard()->pressKey('ENTER'); // Enter for submitting your selection
EDIT:
http://www.anitpatel.net/2012/02/25/selenium-webdriver-how-to-click-on-a-hidden-link-or-menu/
This one explains it in java but basically what he does is a mouse over/hover and wait.
Then he clicks on the element.
I'm not a java genius but it's an example how to work with it.
You can use the:
string mouseOver(string $locator)
This simulates a user hovering a mouse over the specified element.
http://docs.tadiavo.com/phpunit/www.phpunit.de/pocket_guide/3.1/en/selenium.html
Check if the element is visible using the xpath of the required option value.
$this->isElementPresent($xpath);
$this->click($xpath);
If it is true, then click() method selects the specified option.