Can't find an element with Selenium Python that actually is on the source code - python-3.x

I can't find an element and get an error, but I actually see it when inspecting the element, but if I "print" driver.page_source I can't see it.
def screenname():
driver.find_element(By.XPATH, '//*[#id="indium_view_form_BooleanCheckBox_1"]').click()
screenname()
#also tried ID and CSS Selector
#THE CODE I SEE FROM INSPECTING THE ELEMENT
#<input name="nameTransposition" type="checkbox" role="checkbox" aria-checked="false" class="dijitReset dijitCheckBoxInput" data-dojo-attach-point="focusNode" data-dojo-attach-event="ondijitclick:_onClick" value="on" tabindex="0" id="indium_view_form_BooleanCheckBox_1" style="user-select: none;">
This is the error I get
#selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"xpath","selector":"//*[#id="indium_view_form_BooleanCheckBox_1"]"}
Click on the element

Maybe it's not loaded yet? Try to wait until this element shows up
from selenium.webdriver.support.wait import WebDriverWait
element = WebDriverWait(driver=driver, timeout=timeout).until(
method=expected_conditions.presence_of_element_located(
locator=(
By.XPATH,
"""//*[#id="indium_view_form_BooleanCheckBox_1"]""",
),
)
)
element.click()

Related

ElementNotInteractableException: Message: element not interactable: [object HTMLDivElement] has no size and location error using Selenium and Python

I am trying to click show results button after selecting filter on linkedin. I have correctly found the button element but it is giving me this error:
selenium.common.exceptions.ElementNotInteractableException: Message: element not interactable: [object HTMLDivElement] has no size and location
Here is my piece of code that I have tried:
element = WebDriverWait(self, 10).until(EC.presence_of_element_located((By.CSS_SELECTOR, 'div[class="artdeco-hoverable-content__shell"]')))
box = self.find_element_by_css_selector('div[class="artdeco-hoverable-content__shell"]')
ele = box.find_element_by_css_selector('button[data-control-name="filter_show_results"]')
ActionChains(self).move_to_element(ele).click(ele).perform()
I have also tried:
self.execute_script("arguments[0].click();", ele)
What's the reason behind this?
HTML of the results button:
<div class="reusable-search-filters-buttons display-flex justify-flex-end mt3 ph2">
<button data-test-reusables-filter-cancel-button="true" data-control-name="filter_pill_cancel" aria-label="Cancel Locations filter" id="ember429" class="artdeco-button artdeco-button--muted artdeco-button--2 artdeco-button--tertiary ember-view" type="button"><!---->
<span class="artdeco-button__text">
Cancel
</span></button>
<button data-test-reusables-filter-apply-button="true" data-control-name="filter_show_results" aria-label="Apply current filter to show results" id="ember430" class="artdeco-button artdeco-button--2 artdeco-button--primary ember-view ml2" type="button"><!---->
<span class="artdeco-button__text">
Show results
</span></button>
</div>
Edit 2: Here is the image of the button , I am trying to click.
https://ibb.co/4Y7VN0j
Edit 3: Image with dev tools open : https://ibb.co/CJdtNM1
The desired element is a Ember.js enabled element, so to click on the Show results button instead of presence_of_element_located() you need to induce WebDriverWait for the element_to_be_clickable() and you can use either of the following locator strategies:
Using CSS_SELECTOR:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button[data-control-name='filter_show_results'][aria-label='Apply current filter to show results'] span.artdeco-button__text"))).click()
Using XPATH:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//button[#data-control-name='filter_show_results' and #aria-label='Apply current filter to show results']//span[contains(., 'Show results')]"))).click()
Note: You have to add the following imports :
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC

Using Selenium and Python to Click on a button below searched element

I am trying to test downloading a file from a website using selenium on python.
The website has peculiar design where the file name appears as a text element above the button to download the file. There are no specific names or IDs for these buttons. And they are not known to us. So, I can't specify the ID or element name in the code directly.
Here is the HTML snippet:
<div class="col-xs-12 col-sm-12 col-md-12 col-lg-12 noborderBottom semiBolder-label ">
<span data-bind="text: jurisdictionName, attr: { id: jurisdictionId() + '-guides' }, visible: showInList" id="67-guides">Greece</span>
</div>
<div class="clearfix visible-xs"></div>
<div class="col-xs-6 col-sm-6 col-md-5 col-lg-5 text-center">
<div class="greenPDFIcon cursorPointer align-center" data-bind="event: { click: onHighlightClick.bind($data) }, style: { 'visibility': highLightUrl() ? 'visible' : 'hidden' }" style="visibility: visible;"></div>
<span class="taxGuidesText lg-visible md-visible xs-visible" data-bind="style: { 'visibility': highLightUrl() ? 'visible' : 'hidden' }" style="visibility: visible;">Highlights</span>
<!--<span class="taxGuidesText lg-visible md-visible xs-visible" data-bind="visible:showInList">Highlights</span>-->
</div>
Now, I first need to search for the text "Greece" in the above example.
Get it's location on the webpage:
class="col-xs-12 col-sm-12 col-md-12 col-lg-12 noborderBottom semiBolder-label"
Locate the button right below this text - so in the above example that gives me:
class="col-xs-6 col-sm-6 col-md-5 col-lg-5"
And then click on the button:
class="greenPDFIcon cursorPointer align-center"
The thing is, I do not know this "Greece". That comes through input parameter.
I only know that if the input parameter text is found on the webpage, the button will be right below it. And I have to click it to open the pdf file.
How to do that using selenium on python?
So far I have reached:
s=Service(r"driver_path")
browser = webdriver.Edge(service=s)
browser.get('webpage_url')
country = input('Enter a country name: ')
Also, suggest if I should use anything else rather than selenium to do this, as I understand this is more of web-scrapping than automated testing. I also tried beautifulsoup, but the website is not accessible directly through api. Browser access is required.
To locate the element with the country name e.g. Greece and click on the respective element with text as Highlights you can use the following Locator Strategies:
Using XPATH and "Old Style" String Formatting (% Operator):
browser.get('webpage_url')
country = input('Enter a country name: ')
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//div[contains(#class, 'semiBolder-label')]//span[contains(., '%s')]//following::div[2]//span[contains(., 'Highlights')]" % country))).click()
Using XPATH and "New Style" String Formatting (str.format):
browser.get('webpage_url')
country = input('Enter a country name: ')
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//div[contains(#class, 'semiBolder-label')]//span[contains(., '{}')]//following::div[2]//span[contains(., 'Highlights')]".format(country)))).click()
Using XPATH and String Interpolation / f-Strings (Python 3.6+):
browser.get('webpage_url')
country = input('Enter a country name: ')
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, f"//div[contains(#class, 'semiBolder-label')]//span[contains(., '{country}')]//following::div[2]//span[contains(., 'Highlights')]"))).click()
Note: You have to add the following imports :
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC

Unable to locate element error while trying to locate an input box element using Selenium through Python

I´m trying to find a text box with Python and Selenium.. I Tried by_css_selector, bY XPATH, by ID, by name but the message is always the same:
Unable to locate element: #x-auto-225-input
this is the piece of html. I Want to find the textbox to fill it.
<td class="x-table-layout-cell" role="presentation" style="padding: 2px;">
<div role="presentation" class=" x-form-field-wrap x-component" id="x-auto-225" style="width: 150px;"></div>
<input type="text" class=" x-form-field x-form-text " id="x-auto-225-input" name="PURCHASE_ORDER_CODE_NAME" tabindex="0" style="width: 150px;">
</td>
My last attempt was:
pc = browser.find_element_by_css_selector("#x-auto-225-input").click()
pc.send_keys("7555425-1")
Looking at the html, id mentioned can be dynamic, so you can't put the static id in your identifier.
However, as name attribute is present in the html, you can use that to identify your element, like:
browser.find_element_by_name("PURCHASE_ORDER_CODE_NAME").click()
Updated answer as per discussion with the OP
As an iframe is present on the UI, you need to first switch to the iframe and then click on the element.
To switch to iframe you can use:
browser.switch_to.frame(browser.find_element_by_tag_name('iframe'))
and then use:
pc = browser.find_element_by_name("PURCHASE_ORDER_CODE_NAME")
pc.click()
pc.send_keys("7555425-1")
if you want to switch back to the default content, you can use:
browser.switch_to.default_content()
The desired element is a dynamic element so to invoke click() on the element you have to induce WebDriverWait for the element to be clickable and you can use either of the following Locator Strategies:
Using CSS_SELECTOR:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "input.x-form-field.x-form-text[id$='-input'][name='PURCHASE_ORDER_CODE_NAME']"))).click();
Using XPATH:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//input[#class=' x-form-field x-form-text ' and contains(#id,'-input')][#name='PURCHASE_ORDER_CODE_NAME']"))).click();
Note : You have to add the following imports :
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
Maybe you can try another "selector" approach. Ex(Javascript):
selenium.By.xpath('//*[#data-icon="edit"]')
driver.findElement(by).click()

How to Click Link Being Covered by Another Element? Python 3.6 and Selenium

Having trouble figuring out how to click the Next button at the bottom of the table on this page:
https://www.zacks.com/stocks/industry-rank/reit-and-equity-trust-other-266/stocks-in-industry
This is what I've tried:
from bs4 import BeautifulSoup
import requests
import csv, random, time
from pandas.io.html import read_html
from selenium import webdriver
from selenium.webdriver.support.ui import Select
url = 'https://www.zacks.com/stocks/industry-rank/reit-and-equity-trust-other-266/stocks-in-industry'
# Open Chrome
driver = webdriver.Chrome()
# Send Chrome to the URL
page = driver.get(url)
# Wait for page to load a few seconds
timeDelay = random.randrange(4, 8)
time.sleep(timeDelay)
# Try to click the darn button
element = driver.find_element_by_xpath('//*[#id="industry_rank_table_next"]')
driver.execute_script("arguments[0].click();", element)
...and
element = driver.find_element_by_xpath('//*[#id="industry_rank_table_next"]')
element.send_keys("\n")
...found from other answers but not working for me. Simply using .click() does not work. I've also tried selecting the button using css_selector, partial_link_text, and class_name but still no success. I've ran into this on a few sites. Any ideas?
To click() on the element with text as Next you have to induce WebDriverWait for the element to be clickable and you can use either of the following solutions:
Using LINK_TEXT:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.LINK_TEXT, "Next"))).click()
Using CSS_SELECTOR:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "a.paginate_button next#industry_rank_table_next"))).click()
Using XPATH:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//a[#class='paginate_button next' and #id='industry_rank_table_next']"))).click()
Note : You have to add the following imports :
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
if the element which you have to click have parent element then you can find parent by findElements method and after than you just need to pass the index of the element like 0 or 1 or so on.. and then you can perform click action on that
Want to click on third li from second ul:
<ul id="select-123" style="width: 1180px; display: none;">
<li class="" style="display:none;">
<li class="">
<li class="">
<li class="">
</ul>
<ul id="select-123" style="width: 1180px; display: none;">
<li class="" style="display:none;">
<li class="">
<li class="">
<li class="">
</ul>
Code I am trying is to select third li from second ul which does not work:
driver.findElements(By.css(ul[id*='select-123'])).then(function(elems) {
elems[2].then(function(lis) {
driver.findElement(By.css("ul[id*='select-123'] li:nth-child(3)")).click();
});
});
Another way if you don't wish to add additional wait(s) to your code and just click the button:
using javascript click:
element = driver.find_element_by_xpath("//a[#class='paginate_button next' and #id='industry_rank_table_next']")
driver.execute_script("arguments[0].click();", element)
UPDATE:
I didn't notice this earlier, but
element = driver.find_element_by_xpath('//*[#id="industry_rank_table_next"]')
driver.execute_script("arguments[0].click();", element)
...works as it clicks the link successfully, but gives me a
selenium.common.exceptions.WebDriverException: Message: unknown error: call function result missing 'value'
...error after it clicks the link. So to get around this, I've just added a try/except to handle the error. ie:
try:
element = driver.find_element_by_xpath('//*[#id="industry_rank_table_next"]')
driver.execute_script("arguments[0].click();", element)
except:
pass
...which seems to work. Seems like such a stupid observation on my part, but thank you to everyone for your help. Hopefully something in here will help someone else in the future.

how to click on the first result of a search on metacritc with selenium

how do I click on the first search result on metacritc's search bar?
this is what I have so far:
self.search_element = self.driver.find_element_by_name("search_term")
self.search_element.clear()
self.search_element.send_keys(self.game_line_edit.text())
self.link_to_click = self.driver.find_element_by_name("search_results_item")
self.link_to_click.click()
# self.game.setText(self.driver.find_element("search_results_item"))
self.game_line_edit.setText("")
self.driver.close()
but I'm getting this error:
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"name","selector":"search_results_item"}
I realize selenium can't find the link but I am not sure what element it is
this is the HTML I'm trying to click on:
<a class="search_results_item" href="https://www.metacritic.com/game/pc/into-the-breach">
<span class="metascore_w score_outstanding">90</span>
<span class="title" data-mctitle="Into the Breach"><b>Into the</b> Breach</span>
<span class="type secondary">PC Game</span>
<span class="separ secondary">,</span>
<span class="date secondary">2018</span>
</a>
can someone help?
Thanks!
You are searching by name when you are referring to a class. Instead use a CSS selector, e.g.
.find_element_by_css_selector(".search_results_item")
.search_results_item indicates a class with the name 'search_results_item'.
If that doesn't work, you probably need a wait. See this answer for more info.
If you're fine with using xPath, you can select by index.
(//a[contains(#class,'search_results_item')])[1]
#JeffC is also correct as well. You should not select by name because this element has no name. At the very least, select by class or tag.

Resources