I have a button that when I click it I will get a sort of a dropdown list. My problem is that I want to click one of the options in this dropdown list but I don't see how to refer to it.
I have tried to act as if this was a list box and I used the "Select" module but I failed with exceptions. My purpose is to be able to refer to any of the options in this dropdown list. Could it be that the HTML code is missing a unique href value ?
<input name="Port 19" value="Uplink" class="ExtendedButton" onclick="SelectFrame('Uplink-200')" id="Port-19" style="width: 84px; display: inline;" type="button">
<script>writeUplinkDropDown()</script>
<div class="dropdown-content">
200G
100G #1
100G #2
</div>
First thing you will need to do is open the dropdown menu. Once the menu is open you can click on any of those options you posted by using any of the following selector examples:
driver.find_elements_by_css_selector('a[onclick="SelectFrame(\"Uplink-200\")"]')
driver.find_elements_by_css_selector('a[onclick="SelectFrame(\"Port-19\")"]')
driver.find_elements_by_css_selector('a[onclick="SelectFrame(\"Port-20\")"]')
Selenium's Select class only works with native <select> elements. Because you have implemented a dropdown with custom HTML, you won't be able to use it.
Instead, in order to select one of the options in your custom dropdown, you'll need to perform each of the actions that a real user would:
clicking the button that opens the dropdown, then
clicking the link for the desired option.
Note: When searching for elements on a page, always try to use the same criteria that a real user would. A real user would look for a link with some meaningful text, e.g., "200G"; they would not go scouring the source code looking for a particular onclick attribute. (What's more, the onclick attribute is a part of the implementation of the page, not the interface, and shouldn't be relied upon as such, as it could change at any time.)
1. Using Selenium
Selenium doesn't provide an explicit method for finding buttons, but you can use CSS or XPath to do that:
driver.find_element_by_css_selector("input[type='button'][value='Uplink']")
driver.find_element_by_xpath("//input[#type = 'button'][#value = 'Uplink']")
To find links, Selenium conveniently provides find_element_by_link_text():
driver.find_element_by_link_text("200G").click()
driver.find_element_by_link_text("100G #1").click()
driver.find_element_by_link_text("100G #2").click()
2. Using Capybara (which uses Selenium)
Bare Selenium can be fickle. The link may not yet be in the DOM. Or it may not yet be visible.
capybara-py addresses these problems transparently:
page.click_button("Uplink")
page.click_link("200G")
page.click_link("100G #1")
page.click_link("100G #2")
Related
I am writing a QA automation script using Python and Selenium.
I want to check if the input is already focused when the webpage is rendered.
My problem is that I can't find a way to get the currently focused input that is inside the shadow dom.
HTML doc looks like this:
<div>
#shadow-root
# this input element is already focused when the page is rendered
<input type='text'>
</div>
I've tried driver.switch_to.active_element but it always returns None, probably because it can't access shadow dom.
I hope anyone knows another way to get the currently focused input element inside a shadow dom
When the webpage is rendered though you observe that the <input> is already focused but Selenium's focus is at the Top Level Browsing Context.
So to identify the <input> element you need to bring Selenium's focus within the shadow-root first.
You can find a relevant detailed discussion in PrintText-How to extract info within a #shadow-root (open) using Selenium Python
I am using Python and Selenium to scrape a web page.
I am trying to find the following 'next page' button in the page:
<button class="pagination__next" aria-label="click to go to the next page" disabled="true" aria-hidden="true"></button>
disabled='true' appears when I'm on the last page of a multi-page embedded javascript generated table.
There may be more buttons on the page and some are disabled at the time I'm looking for this particular button.
So what I'm trying to do is determine if this particular button which has class="pagination__next" with attribute disabled equals 'true' is in driver.page_source
There are plenty of examples around about identifying the particular tag ('button'). But not how to find the button and the button attribute disabled equal to 'true'
I tried various approaches. I think the closes I got was:
driver.find_element_by_css_name('pagination__next[disabled='true'])
but I don't think it worked.
There is an identical question here but OP asks for Java solution. I'm looking for Python.
Guidance please.
find_element_by_xpath() with multiple attributes is what you need, i.e.:
driver.find_element_by_xpath('//*/button[#class="pagination__next"][#disabled="true"]')
Using .find_element_by_xpath with the AND expression:
driver.find_element_by_xpath('//button[#class="pagination__next" and #disabled="true"]')
With the AND expression you can locate element with more than one condition using the attribute value.
xpath-selenium OR & AND expression
yeah, there are similar question, but upon reading through them I weren't able to find a solution for my problem.
Following situation: I'm tryin to click the "reply" button on "https://charleston.craigslist.org/ctd/d/charleston-2018-nissan-sentra-sedan-4d/7108660907.html" and after executing this click a popups shows up where I shall click another button, but let's start with the first button as the "reply" click itself is very trouble-making.
The reply button has the following X-Path:
'/html/body/section/section/header/div[2]/div/button'
speaking of which the source code is:
<button role="button" class="reply-button js-only" data-href="/__SERVICE_ID__/chs/ctd/7108660907">
reply
</button>
(see code on mentioned website).
However, my approach with Selenium (Python) doesn't work:
reply_button = '/html/body/section/section/header/div[2]/div/button'
driver.get('https://charleston.craigslist.org/ctd/d/charleston-2018-nissan-sentra-sedan-4d/7108660907.html')
driver.find_element_by_xpath(reply_button).click()
Everytime I tried, the website just loads up properly (even with implementing time.sleep(x)) and tries to click the button, but this fails and the website just refreshes - my guess is that they either regocnize the browser being Selenium-controlled, that the click isn't legitimate or that I didn't catch anything right in my code.. Anyone able to help out?
Btw I already tried searching "by_class_name", that didn't work either.
This Xpath: '/html/body/section/section/header/div[2]/div/button' is like when you get a map with instructions like step forward until you see a car then turn left 30° then step forward until you see a tree then hop twice then go to the second house to your right. Not safe to use, avoid such paths. If the page layout changes, your path may become invalid.
Try this:
button = driver.find_element_by_xpath('//*[#class="reply-button js-only"]')
button.click()
Clicking the button opens a "show phone number" popup (which may be located by driver.find_element_by_xpath('//*[#class="show-phone"]')).
Explanation:
If you want proper Xpath, inspect what you want to interact with. The button you want to click is this:
<button role="button" class="reply-button js-only" data-href="/__SERVICE_ID__/chs/ctd/7108660907">
reply
</button>
You can see that it has no "id" tag but it is a button with a specific class. You may copy right away the "class" part -> class="reply-button js-only"
Now you can check if is it unique enough:
driver.find_elements_by_xpath('//*[#class="reply-button js-only"]')
If "find elements" returns a single result, usually you should be OK. You can see that all I did is that I pasted the class inside this: driver.find_elements_by_xpath('//*[# and this ]').
If you need more accuracy, you can specify that it is a button:
driver.find_element_by_xpath('//button[#class="reply-button js-only"]')
Or it is the direct child of the element with class: class="actions-combo", so a more safe path would be:
driver.find_element_by_xpath('//*[#class="actions-combo"]/button[#class="reply-button js-only"]')
This pattern works for all webelement attributes, not just for classes. You could use the role="button" too for more filtering. Look up for Xpath, it is a pretty neat stuff.
I am using selenium with python to try and click through a dropdown menu. However the options the dropdown menu produces are not visible in the source code of the webpage.
I have not been able to find a way that lets me select an item in the dropdown by name.
So far I am able to login and click on the menu to produce the dropdown as such:
courses = driver.find_element_by_link_text("Select a course...").click()
However after this, I am not sure how to access and click the elements produced by the above click.
Here is a snippet of the HTML that activates the dropdown.
<a class="d2l-menuflyout-opener d2l-clickable" onclick="return false;" aria-haspopup="true">
<span class="d2l-menuflyout-text d2l-menuflyout-emphasis">Select a course...</span><span class="d2l-menuflyout-arrow d2l-menuflyout-arrow-open d2l_1_41_179"></span><span class="d2l-menuflyout-arrow d2l_1_40_548 d2l-menuflyout-arrow-closed"></span>
Here is a screenshot of what the menu looks like after the .click() call.
screenshot
Once the menu opens, I am not sure how to select the one I want since I don't know how the values or id's of the options are stored as it is not in the source code.
What you have shared in your html, Select a course... is not a link text it is under span tag you need to try alternative like
driver.find_element_by_xpath(".//a/span[contains(text(),'Select a course')]").click()
I'm using a page that has out of the ordinary elements. Some of which are buttons that cannot be clicked using an xpath, link text, or id locator.
Here is the html for one button.
<div class="goog-inline-block goog-custom-button-inner-box">Save & Go Back</div>
How should I go about including these kinds of buttons and objects in my script?
You could use a CSS selector
driver.find_element_by_css_selector("div.goog-inline-block.goog-custom-button-inner-box").click()
I would say use the class, but it has a compound class name so I don't think that will work. Ask the developer to put an ID on the button.