python selenium click on button without Id and name - python

I have one button, and I want to click on this button , I do
login_form = driver.find_element_by_xpath("/html/body/div/h1/div[1]").click();
my code :
driver = webdriver.Firefox()
driver.get('http://www.textdet.com/')
e = driver.find_element_by_id("imagefile")
e.send_keys("/home/brm17/Desktop/ProjetFinDetude/image.png")
login_form = driver.find_element_by_xpath("/html/body/div/h1/div[1]").click();
But I get:
selenium.common.exceptions.NoSuchElementException: Message: Unable to
locate element: /html/body/div/h1/div[1]
how to click on button Download bounding boxes on python by selenium , the html
<h1 style="position: relative">Scene Text Detection Demos
<div aria-label="..." role="group" class="btn-group" style="position: absolute; bottom: 10px; right: 0px;">
<!--<button id="toggle_text_propoals" type="button" class="btn btn-success btn-sm">Show text proposals</button>-->
Download bounding boxes
</div>
</h1>

The button is in <a> tag, not <div> tag. You also have only one <div> so div[1] is invalid. You can search by the text
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
button = WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.XPATH, '//a[contains(., "Download bounding boxes")]')))
button.click();
Or by class since you have only one button so class btn should be unique.
driver.find_element_by_class_name('btn').click(); # or 'btn-success' or 'btn-sm'
By the way, click() doesn't return anything, you can't assign it to login_form.

The button is under an <a> tag so we write code for Xpath:
driver.find_element_by_xpath("//a[. = 'Download bounding boxes']").click()
so it finds the text is "Download bounding boxes" on the website and clicks on it.
In the code above // a is written because the button was inside the <a> tag we can write //span,//div as well if the code was under a span or divtag.

Related

Selenium: Cant select/click button in modal. Modal appears after try:except

I am running into an issue where I am unable to select a button in the modal. The modal only appears when running my selenium script and does not appear when manually traversing the webpage. Interestingly enough the modal does consistently appear when my script runs try/except as shown below, but the program advances to the next step and is not able to get the element to click. Trying to get the element after this try:except also fails. The modal does not show up otherwise.
try:
element=driver.find_element_by_xpath('//div[contains(#href,"appointment")]')
element.click()
print("Looking for the modal button")
except NoSuchElementException:
print("*****Did not find the modal button")
I have tried the following with no success:
WebDriverWait(driver, 300).until(EC.element_to_be_clickable((By.XPATH, "//button[#class='btn btn-default btn-ok'][#data-dismiss='modal']"))).click() This simply times out.
Different methods to get the element:
element = driver.find_element_by_class_name("btn.btn-default.bt-ok")
and
element=driver.find_element_by_xpath('//div[contains(#href,"appointment")]')
In both cases the element is not found.
Tried running with cookies, and the result is the same.
Tried various sleep timers, but the modal does not appear during this sleep period
Here is the HTML Snippet of this section. Not sure if <div class =schedule-modal is a hint that there is some logic behind how/when the modal shows up?
<div class="schedule-modal modal fade in" tabindex="-1" role="dialog" aria-hidden="false" style="display: block;">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-body">
<p><strong> Text
</p>
</div>
<div class="modal-footer">
<a class="btn btn-default btn-ok" href="/appointment">Start Appointment</a>
</div>
</div>
</div>
</div>
Thanks in advance for your help!
Update
Looks like the above code exists HTML code exists on the source page before the modal pops up which is why I was not able to access the element. My next question is what is this schedule-modal function doing:
function showNotice(dom) {
var $scheduleModal = $(".schedule-modal");
if ($scheduleModal.length) {
var link = $(dom).attr('href');
$scheduleModal.find('.btn-ok').attr('href', link);
$scheduleModal.modal('toggle');
return false;
}
it looks like you are trying to find a div element with an href attribute containing appointment. you'll want to select the a element, which is the element that actually contains the reference you are trying to select. you have two options:
driver.find_element_by_xpath('//a[contains(#href,"appointment")]')
or
driver.find_element_by_xpath('//div/a[contains(#href,"appointment")]')
both will achieve the same results. but you may want to refine the selection just in case there are multiple a tags that have an href attribute contianing appointment
If you are unsure if the modal element would appear or not you can wrap up the click to the modal button within a try-catch{} block inducing WebDriverWait for the element_to_be_clickable() and catching TimeoutException and you can use the following Locator Strategy:
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException
try:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//*[contains(., 'login or register')]"))).click()
print("Modal button clicked")
except TimeoutException:
print("Modal button was not found")

Can't upload image on LinkedIn using Selenium / wired text pops (data-artdeco-is-focused="true")

I am making a program that will automatically post image on LinkedIn.
It is only able to click on the 'Photo', after that it does't click on anything.
I found that when I try to select the 'select images to share' button, it does't work.
So, I manually clicked on 'select images to share' button and in the second line of the HTML code, this popped from nowhere :
data-artdeco-is-focused="true"
And, when I try to copy it by clicking on HTML code on the browser, it hides the code.
This is the HTML code: (<data-artdeco-is-focused="true"> appeared in the end of second line of the HTML code below)
<div class="image-sharing-detour-container">
<input id="image-sharing-detour-container__file-input" class="image-sharing-detour-container__media-button visually-hidden" name="file" multiple="" filecountlimit="9" accept="image/gif,image/jpeg,image/jpg,image/png" type="file">
<div class="image-sharing-detour-container__upload-media-button">
<label for="image-sharing-detour-container__file-input" class="artdeco-button artdeco-button--tertiary">
Select images to share
</label>
</div>
<!----> <div class="share-box-footer ">
<div class="share-box-footer__main-actions">
<button id="ember421" class="artdeco-button artdeco-button--2 artdeco-button--secondary ember-view" type="button"><!---->
<span class="artdeco-button__text">
Cancel
</span></button>
<button disabled="" id="ember422" class="ml2 artdeco-button artdeco-button--2 artdeco-button--primary artdeco-button--disabled ember-view" type="button"><!---->
<span class="artdeco-button__text">
Done
</span></button>
</div>
</div>
</div>
This is my python code so far;
from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from time import sleep as slp
#open browser & visit linkedin
driver = webdriver.Chrome("/Users/....../chromedriver")
driver.get('https://www.linkedin.com/')
#enter user/pass & click submit
username = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "input[name='session_key']")))
password = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "input[name='session_password']")))
username.clear()
username.send_keys("user#gmail.com")
password.clear()
password.send_keys("mypasswordhere")
button = WebDriverWait(driver, 2).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button[type='submit']"))).click()
#go to company page
checkpoint = driver.get('https://www.linkedin.com/company/1234567/admin/')
#click on photo and add an image
addphoto = driver.execute_script("arguments[0].click();", driver.find_element_by_xpath("//button[#aria-label='Add a photo']"))
(Edit: this is the //button[#aria-label='Add a photo'] in th HTML code)

Click through dropdown menu with selenium

I am trying to create flashcards on quizlet.com with selenium. If you visit, you will see a "Create" button (or just a "+" depending on window size) in the navbar, when you click this it turns into a dropdown menu with 3 more buttons: 'Study Set', 'Folder' and 'Class'. (I am trying to click Study Set)
First, I am not even sure If I need to have selenium click the first 'Create' button to access the 'Study Set' button or if I can just jump straight to the 'Study Set' button. Anyway, here is the html related to the 'Create' button and 'Study Set' button, respectively:
<button type="button" aria-label="Create"><span>Create</span>/button>
and: (Note, all 3 buttons share the class 'UILink', the first button is the 'Study Set' button and the comments are mine)
<div class="s1ovpdog"> <!-- going to grab this div first because theres 85 elements with the class 'UILink' on the page, grabbing this div cuts it to 3-->
<button class="UILink" type="button"> <!-- then going to grab this button-->
<div class="c1ap9d88">
<div class="iiekfr8">
<div class="i1q3l8tw">
<svg aria-label="sets" class="AssemblyIcon AssemblyIcon--medium" role="img"><noscript></noscript>
<use xlink:href="#sets"></use><noscript></noscript></svg><span class="AssemblyMenuItem--title t1nsp0j0">Study set</span>
</div>
</div>
</div>
</button>
<button class="UILink" type="button">
<div class="c1ap9d88">
<div class="iiekfr8">
<div class="i1q3l8tw">
<svg aria-label="folder" class="AssemblyIcon AssemblyIcon--medium" role="img"><noscript></noscript>
<use xlink:href="#folder"></use><noscript></noscript></svg><span class="AssemblyMenuItem--title t1nsp0j0">Folder</span>
</div>
</div>
</div>
</button>
<button class="UILink" type="button">
<div class="c1ap9d88">
<div class="iiekfr8">
<div class="i1q3l8tw">
<svg aria-label="class" class="AssemblyIcon AssemblyIcon--medium" role="img"><noscript></noscript>
<use xlink:href="#class"></use><noscript></noscript></svg><span class="AssemblyMenuItem--title t1nsp0j0">Class</span>
</div>
</div>
</div>
</button>
</div>
Python code:
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
driver = webdriver.Chrome('./chromedriver')
driver.get("https://quizlet.com")
# Code to log in to quizlet omitted...
# Grab and click first 'Create' button
create_button = driver.find_element_by_xpath("//button[#aria-label='Create']") # only one element has this aria-label
create_button.send_keys(Keys.RETURN) # doesn't display drop-down menu, makes me think something is wrong here but also does not throw an error
# Grab and click 'Study Set' button
div_containting_study_set_button = driver.find_element_by_class_name('s1ovpdog') # only one element has this class
study_set_button = div_containting_study_set_button.find_elements_by_class_name('UILink')[0] # returns 3 buttons, only need first one
study_set_button.send_keys(Keys.RETURN) # Error,ElementNotInteractableException
When I run this, it throws
raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.ElementNotInteractableException: Message: element not interac
table
Though study_set_button should definitely be referencing a button element, I believe? Thanks for any help with this.
EDIT:
Upon searching, I found is_displayed() and ran
create_button.is_displayed() # True
study_set_button.is_displayed() #False
this returns True and False, respectively. Think my problem lies somewhere there.
This is what I found to work. It was not easy to find a unique locator for "Study set" inside the dropdown. There are two "Study set" elements on the page and the first one in the DOM is not visible. I added the waits just to be safe since you are clicking and the dropdown has to load. You may not need the waits but it won't hurt to have them (it won't slow anything down) just in case.
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
wait = WebDriverWait(driver, 10)
wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button[aria-label='Create']"))).click()
wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "div.UIOverlayTrigger-content svg[aria-label='sets'] + span"))).click()

How to make textbox input in selenium with xpath

I made script that automatically picks a product from kith.com and go to the checkout:
element3 = driver.find_element_by_xpath('//*[#id="CheckoutData_BillingFirstName"]')
element3.send_keys("My First Name")
Kiths website:
<div class="col-sm-8 col-xs-12 fval">
<input class="form-control input-validation-error" data-val="true" data-val-countryaddressvalidation="" data-val-countryaddressvalidation-countryaddressvalidationpropname="" data-val-required="Billing First Name is required" data-val-unsupportedcharacters="Please use English characters only" data-val-unsupportedcharacters-unsupportedcharacterspattern="^[A-Za-z0-9,""'`\s#&%$#\*\(\)\[\]._\-\s\\/]*$" id="CheckoutData_BillingFirstName" maxlength="40" name="CheckoutData.BillingFirstName" placeholder="First Name" type="text" value=""><span class="glyphicon glyphicon-remove form-control-feedback" aria-hidden="true"></span>
</div>
How can I locate the input form and send keys to it?
I am getting the same error every time :
Unable to locate element: {"method":"xpath","selector":"//*[#id="CheckoutData_BillingFirstName"]"}
Your target element inside a <frame>:
<iframe src="https://fs.global-e.com/Checkout/v2/f77781eb-a7c0-43e2-822a-3ca96e8658f0?gaSesID=361925132.674171348.583&gaMerchantClientInfo=undefined#undefined&chkcuid=3ef950c0-4c7d-4cfe-bab5-3a1ed7035318&isNECAllowed=true&vph=631&ift=87" class="Intrnl_CO_Container" id="Intrnl_CO_Container" name="Intrnl_CO_Container" allowtransparency="true" width="100%" scrolling="no" marginheight="0" marginwidth="0" frameborder="0" height="1000px" style="height: 2196px;"></iframe>
You need to switch it first:
#after clicked checkout button
time.sleep(10)
driver.switch_to.frame(driver.find_element_by_id("Intrnl_CO_Container"))
time.sleep(10)
element3 = driver.find_element_by_xpath('//*[#id="CheckoutData_BillingFirstName"]')
element3.send_keys("My First Name")
But there is a better way to wait in selenium, for detail you can read the #pcalkins suggestion.
After clicked checkout button, you can add following code:
#after clicked checkout button
wait = WebDriverWait(driver, 20)
wait.until(EC.frame_to_be_available_and_switch_to_it((By.ID, 'Intrnl_CO_Container')))
element3 = wait.until(EC.element_to_be_clickable((By.XPATH, '//*[#id="CheckoutData_BillingFirstName"]'))).click()
element3.send_keys("My First Name")
Please import:
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

How to click the close button within a modal window through Selenium and Python

Cannot click button id="close in modal window.
Trying all xpaths like:
//button[#data-dismiss='modal']
//button[#id='close'], //button[#type='button']
//button[contains(.,'Закрыть')]
//button[contains(#data-dismiss,'modal')]
//button[contains(#id,'close')]
Also trying to combine xpaths, but still not working
Code:
<div id="idCardGroupChangeStatusResult" class="modal fade in" tabindex="-1" role="dialog" aria-hidden="false" style="display: block;">
<div class="modal-dialog st-modal-dialog" style="width: 600px; padding-top: 250px;">
<div class="modal-content">
<div class="modal-header st-pad-normal">
<div class="modal-body">
<div class="modal-footer">
<button id="close" class="btn btn-default btn-sm" type="button" data-dismiss="modal"> Закрыть </button>
</div>
</div>
</div>
</div>
Css not working to
Any ideas?
As the element with text as Закрыть is within a Modal Dialog Box so to locate the desired element you have to induce WebDriverWait for the element to be clickable and you can use either of the following solutions:
Using CSS_SELECTOR:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button.btn.btn-default.btn-sm#close[data-dismiss='modal']"))).click()
Using XPATH:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//button[#class='btn btn-default btn-sm' and #id='close'][#data-dismiss='modal']"))).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 element_to_be_clickable not works, try code below to check if there's more than one close buttons on the page. You can use code below to filter by visible or visible and latest one and click on it.
close_buttons = WebDriverWait(driver, 5).until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, "#idCardGroupChangeStatusResult #close")))
# check how many buttons in on the HTML, you can try "visibility_of_all_elements_located"
print(len(close_buttons))
visible_buttons = [close_button for close_button in close_buttons if close_button.is_displayed()]
visible_buttons_len = len(visible_buttons)
print(visible_buttons_len)
visible_buttons[visible_buttons_len - 1].click()
Does the message disappears?
Update, message window disappear:
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.action_chains import ActionChains
driver = webdriver.Chrome()
wait = WebDriverWait(driver, 5)
actions = ActionChains(driver)
#...
status_message = wait.until(
EC.visibility_of_element_located((By.CSS_SELECTOR, "#idCardGroupChangeStatusResult")))
actions.move_to_element(status_message).perform()
# here you can get text from message window, check/assert ..
status_message.find_element_by_css_selector("#close").click()

Categories

Resources