Unable to locate elements which really exist in Selenium - python

unable to locate element in selenium. that is actually a shopify App on shopify store developed using python. when ever i try to select any element on app error appearing unable to locate element
time.sleep(2)
driver.find_element_by_xpath('//*[#id="navbar"]/div/ul/li[2]/a').click()
front end code
<td class="text-start"><button type="button" class="v-btn v-btn--flat v-btn--icon v-btn--round v-btn--text theme--light v-size--default" role="button" aria-haspopup="true" aria-expanded="false"><span class="v-btn__content"><i aria-hidden="true" class="v-icon notranslate mdi mdi-dots-vertical theme--light"></i></span></button><div class="v-menu"><!----></div></td>
Trying to select this mentioned in screen shot

Don't rely on sleep(), use Waits
Do you see any <a> in your "front end code"? Neither do I. It's just impossible to select the thing that does not exists, you know :)
Do you really need your selector to be this complicated?
//*[#id="navbar"]/div/ul/li[2]/a
Or is it possible to use sort of a class or id instead?
What will happen if you won't click on a specific <a> and will try to click a whole list entry?
It's usually enough to click some outer element instead of
complecating XPath selector more and more.

Related

I cannot find a "button onclick" element using Selenium and Python

I am automating a process using Selenium and python. Right now, I am trying to click on a button in a webpage (sorry I cannot share the link, since it requires credential to login), but there is no way my code can find this button element. I have tried every selector (by id, css selector, xpath, etc.) and done a lot of googling, but no success.
Here is the source content from the web page:
<button onclick="javascript: switchTabs('public');" aria-selected="false" itemcount="-1" type="button" title="Public Reports" dontactassubmit="false" id="public" aria-label="" class="col-xs-12 text-left list-group-item tabbing_class active"> Public Reports </button>
I also added a sleep command before this to make sure the page is fully loaded, but it does not work.
Can anyone help how to select this onclick button?
Please let me know if you need more info.
Edit: you can take a look at this picture to get more insight (https://ibb.co/cYXWkL0). The yellow arrow indicates the button I want to click on.
The element you trying to click is inside an iframe. So, you need to switch driver into the iframe content before accessing elements inside it.
I can't give you a specific code solution since you didn't share a link to that page, even not all that HTML block. You can see solutions for similar questions here or enter link description here. More results can be found with google search

Can't select Review button

I'm making a simple bot to apply to jobs on LinkedIn easy apply. Usually after clicking apply you fill in the basic info and the next button appears until you have a review button and then a submit application button. I was able to click next using a while loop with this code.
button = driver.find_element_by_css_selector(".artdeco-button--primary") while button: button.click() time.sleep(1.25)
but I get this error when the Review button appears
selenium.common.exceptions.StaleElementReferenceException: Message: stale element reference: element is not attached to the page document (Session info: chrome=102.0.5005.115)
I've tried a lot of different methods, XPath, WebdriverWait, and others but nothing works to click on the Review button with the following element HTML
<button aria-label="Review your application" id="ember562" class="artdeco-button artdeco-button--2 artdeco-button--primary ember-view" type="button"> <span class="artdeco-button__text"></span> </button>
could I get some help figuring out how to select the Review button?
DOM Issue:
This probably has to do with the element not being attached to the DOM. See Selenium Docs on this error.
A common technique used for simulating a tabbed UI in a web app is to prepare DIVs for each tab, but only attach one at a time, storing the rest in variables. In this case, it's entirely possible that your code might have a reference to an element that is no longer attached to the DOM (that is, that has an ancestor which is document.documentElement).
If WebDriver throws a stale element exception in this case, even though the element still exists, the reference is lost. You should discard the current reference you hold and replace it, possibly by locating the element again once it is attached to the DOM.
For your particular example, add the button variable inside your while loop. This will have the button variable be re-referenced each time you click which will make it a part of the current DOM.

Selenium Python XPath Find Element that has a child/grandchild

I'm new to Python Selenium and trying to select the ui-button tag in the following DOM structure:
...
<div>
<ui-button>
<button type='submit'>TEST</button>
</ui-button>
</div>
There's a lot of HTML in this document which I havent included, so I understand that an efficient XPath statement can accomplish this but don't know how to do it.
There's multiple ui-button tags in the page, but only one with a child button type='submit', and the goal is to click on the ui-button tag with selenium. There's no other easy way to identify these tags. So what I was doing was selecting the submit button with a css selector then using XPath to go up 1 parent, but I need to be able to select the ui-button with a single statement.
This is my best attempt:
"./ui-button/input[#type='submit']"
I'm trying to select the ui-button with a child input button that is of type 'submit'.
Thanks in advance
To select the parent ui-button node according to it's child with type='submit' you can use any of the following XPaths:
//ui-button[./button[#type='submit']]
or
//button[#type='submit']/..
or
//button[#type='submit']/../..//ui-button
But all this seems strange to me sense normally you have to click the button element, not element with strange tag name like ui-button.
However if <button type='submit'>TEST</button> is not the immediate child of the ui-button element you can use only one option from the 3 mentioned above with a slight change:
//ui-button[.//button[#type='submit']]
this means: an element with ui-button tag name somewhere on the page having somewhere inside it an element matching //button[#type='submit'] locator
In order to get the full XPath you can go to chrome and simply right-click -> Inspect to go to the chrome developer tools. Then you can right-click on the element in the HTML, go to copy, and click Copy Full XPath. Then you can use find_element_by_xpath(XPath goes here) to find the element.

Can't find element by id using selenium

I am making a script in python that goes on a webpage https://www.realtor.ca/ and searches for a specific location. My problem is at the very beginning. When you open a page in the middle is a large search element. Html for that element is:
<input name="ctl00$elContent$ctl00$home_search_input"
maxlength="255" id="home_search_input" class="m_hme_srch_ipt_txtbox"
type="text" style="display: none;">
I am trying to access the element with find_element_by_id method but I always get the error:Message: Unable to locate element: [id="home_search_input"]
This is my code:
from selenium import webdriver as web
Url = "https://www.realtor.ca/"
browser = web.Firefox()
browser.get(Url)
TextField = browser.find_element_by_id("home_search_input")
Has anyone encountered a similar problem or does anyone know how to fix it?
When navigating to the page, the element with the id home_search_input isn't visibble at first. It seems that this one only gets visible once you click the "Where are you looking" placeholder (which disappears then). You'll need to do this explicitly in your test.
Additionally make sure to use either implicit or explicit wait statements to ensure that the elements you interact with are properly loaded and rendered.
Here's an example for your page using the Java client bindings - Python should be quite similar:
driver.get("https://www.realtor.ca/");
new WebDriverWait(driver, 5).until(ExpectedConditions.elementToBeClickable(By.id("m_hme_wherelooking_lnk"))).click();
driver.findElement(By.id("home_search_input")).sendKeys("demo");

Unable to find an element after selecting an option from a dropdown using Python, Selenium, and ActionChains

This is going to be an easy one for somebody, and turned into a long post for what I think is a simple question.
I am scraping a supplier's site and writing to a csv so that I don't have to manually slog through pages and pages of products. In order to get a product list I run a search with no variables and get the lot. However, if I try to limit my search to in-stock products using a dropdown option my code craps out.
Since this is a 3rd party site I cannot alter the html. Here is a slice of the html from the site (reformatted since it copied very ugly):
<tbody id="adv_search_box">
<tr>
<td class="data-name">Search in category:</td>
<td class="data-input" colspan="2">
<select name="posted_data[categoryid]" class="adv-search-select">
<option value=""> </option>
<option value="257">Hot New Arrivals</option>
<option value="252">In-Stock</option>
...
<button class="button main-button" type="submit" title="Search">
<span class="button-right"><span class="button-left">Search</span></span>
</button>
</td>
</tr>
</tbody>
When I use the following to click the search button, I get everything the supplier has with no regard to status. So this works just fine:
searchButton = driver.find_element_by_xpath('//*[#id="adv_search_box"]/tr[8]/td[2]/button/span/span')
actions = ActionChains(driver)
actions.move_to_element(searchButton)
actions.click(searchButton)
actions.perform()
Then I add code to select the "In-Stock"option in front of the button-click code:
#Select in-stock on search page
InStockSelection = driver.find_element_by_xpath('//*[#id="adv_search_box"]/tr[1]/td[2]/select/option[3]')
actions = ActionChains(driver)
actions.move_to_element(InStockSelection)
actions.click(InStockSelection)
actions.perform()
#Click button
searchButton = driver.find_element_by_xpath('//*[#id="adv_search_box"]/tr[8]/td[2]/button/span/span')
actions = ActionChains(driver)
actions.move_to_element(searchButton)
actions.click(searchButton)
actions.perform()
I get the following error:
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"xpath","selector":"//*[#id="adv_search_box"]/tr[8]/td[2]/button/span/span"}
One final note. I realize that this can be coded in a much, much more compact and elegant way. It is coded like this because I'm not going to look at it again until it breaks (i.e. the supplier changes their site), and if it's coded like my six-year old did it I'll be able to figure out what I did years from now.
Thank you all for your assistance.
Edit 1: It appears to me that straightforward xpath solution will not work. In pseudo-coding-babble, I think the program is focused on the drop down table and can't see the rest of the html. If I could refocus back on the page as a whole it ought to work.
Solution: Programming is to me like magic. It is often what you're not looking at that is the bit you need to watch out for. In this case, there was nothing wrong with the code to select the button. The problem was that the code to select the dropdown option wasn't working correctly, and the click at the end was changing the page focus.
The solution was to change the way the option was located and avoid the action chain.
driver.find_element_by_xpath("//select[#name='posted_data[categoryid]']/option[text()='In-Stock']").click()
Assistance was found in this article: Selenium - Python - drop-down menu option value.
Thank you, MikeJRamsey56, for convincing me to ditch the action chain, and thank you dejavu_cmd_delt for taking the time to answer.
i would suggest to use below xpath as it is free of indexing hassle, assuming that there is only one button in all tr
searchButton = driver.find_element_by_xpath('//*[#id="adv_search_box"]//button[#title="Search"]//span[#class="button-left"])

Categories

Resources