Use selenium to write in and run a code cell in jupyterlab - python

I would like to test a patched implementation of juptyerlab. I was hoping to use selenium to execute "hello world" in a code cell. So far I can log in and create a new notebook:
from selenium import webdriver
driver = webdriver.Firefox()
# assume jupyterlab is running and serving on localhost at port 8888
driver.get("http://localhost:8888")
elem = driver.find_element_by_id("password_input")
password = ""
elem.send_keys(password)
elem = driver.find_element_by_id("login_submit")
elem.click()
elem = driver.find_element_by_css_selector(".jp-Launcher-cwd+ .jp-Launcher-section .jp-LauncherCard")
elem.click()
This creates a new notebook, but now I'm stuck at the point of entering some code in a cell and running it. If I view the page source I don't see any html elements for the cells. But if I enter print("test") in a cell, then driver.page_source contains this (it's pretty nested in other stuff I've omitted too):
<div class="CodeMirror cm-s-jupyter CodeMirror-wrap jp-mod-readOnly">
<div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 0px; left: 0px;">
<textarea
style="position: absolute; bottom: -1em; padding: 0px; width: 1px; height: 1em; outline: currentcolor none medium;"
autocorrect="off" autocapitalize="off"
spellcheck="false" tabindex="0"
wrap="off"></textarea></div>
<div class="CodeMirror-vscrollbar" tabindex="-1"
cm-not-content="true"
style="display: block; bottom: 0px;">
<div style="min-width: 1px; height: 33px;"></div>
</div>
<div class="CodeMirror-hscrollbar" tabindex="-1"
cm-not-content="true">
<div style="height: 100%; min-height: 1px; width: 0px;"></div>
</div>
<div class="CodeMirror-scrollbar-filler"
cm-not-content="true"></div>
<div class="CodeMirror-gutter-filler"
cm-not-content="true"></div>
<div class="CodeMirror-scroll" tabindex="-1" draggable="true">
<div class="CodeMirror-sizer"
style="margin-left: 0px; padding-right: 0px; padding-bottom: 0px;">
<div style="position: relative;">
<div class="CodeMirror-lines" role="presentation">
<div style="position: relative; outline: currentcolor none medium;"
role="presentation">
<div class="CodeMirror-measure">
<pre><span>xxxxxxxxxx</span></pre>
</div>
<div class="CodeMirror-measure">
<pre class="CodeMirror-line"
role="presentation"><span
role="presentation"><span
class="cm-builtin">print</span>(<span
class="cm-string">"test"</span>)</span></pre>
</div>
<div style="position: relative; z-index: 1;"></div>
<div class="CodeMirror-cursors"></div>
<div class="CodeMirror-code"
role="presentation"></div>
</div>
</div>
</div>
</div>
<div style="position: absolute; height: 30px; width: 1px; border-bottom: 0px solid transparent;"></div>
<div class="CodeMirror-gutters"
style="display: none;"></div>
</div>
</div>
I can see where the text for print("text") is (i.e. the deepest nested elements in the above html snippet), but I can't figure out which element here I would be able to send text to or send keys to.
I came across robotframework-jupyterlibrary and it has some clues such as this and this . From those links I see
${JLAB CSS ACTIVE INPUT} ${JLAB CSS ACTIVE CELL} .CodeMirror
and
Add and Run JupyterLab Code Cell
[Arguments] ${code}=print("hello world")
[Documentation] Add a ``code`` cell to the currently active notebook and run it.
Click Element css:${JLAB CSS NB TOOLBAR} ${JLAB CSS ICON ADD}
Sleep 0.1s
${cell} = Get WebElement css:${JLAB CSS ACTIVE INPUT}
Click Element ${cell}
Set CodeMirror Value ${JLAB CSS ACTIVE INPUT} ${code}
Run Current JupyterLab Code Cell
Click Element ${cell}
which makes me think if I select the .CodeMirror element, then I just need to figure out what Get WebElement does in that weird language and how to do it in selenium.
Any ideas?
I've also tried (based on https://stackoverflow.com/a/48723135/1011724 and https://stackoverflow.com/a/50279295/1011724):
from selenium.webdriver.common.action_chains import ActionChains
actions = action_chains.ActionChains(driver)
textarea = driver.find_elements_by_css_selector('.CodeMirror textarea')[0] # tried for [0], [1] ,[2] and [3] which is all of them.
actions.move_to_element(textarea).click().send_keys("testing...").perform()
but I keep getting the error
selenium.common.exceptions.WebDriverException: Message: TypeError: rect is undefined

Code below tested with Chrome, Firefox and jupyterlab latest versions:
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
wait = WebDriverWait(driver, 10)
driver.get("http://localhost:8888")
token = "0107216930d05db8a7c36ad6a73573dd5349c3dd56fee852"
wait.until(EC.element_to_be_clickable((By.ID, "password_input"))).send_keys(token, Keys.ENTER)
# wait for "Python 3" Notebook menu or CodeMirror element if already launched.
wait.until(EC.presence_of_element_located(
(By.CSS_SELECTOR, "[title='Python 3'][data-category='Notebook'], .jp-Notebook .CodeMirror")))
# if "Python 3" Notebook menu found click to open new Notebook
if len(driver.find_elements_by_css_selector("[title='Python 3'][data-category='Notebook']")) > 0:
driver.find_element_by_css_selector("[title='Python 3'][data-category='Notebook']").click()
# wait for CodeMirror and click to focus
code_mirror = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, ".jp-Notebook .CodeMirror")))
code_mirror.click()
code_mirror.find_element_by_tag_name("textarea").send_keys("print('Hello World!')")
driver.find_element_by_css_selector("[data-icon='run']").click()
output = wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, ".jp-OutputArea-output")))
print(output.text)
assert output.text.strip() == "Hello World!"
driver.quit()

To Open Jupyter-Notebook:
Either Open a command window and navigate to the repository folder or Open anaconda-command-prompt window and simply execute
jupyter notebook --NotebookApp.token='' --NotebookApp.password=''
After loading notebook using driver.get("http://localhost:8888"), Here is the most tricky part, that how to select a Dynamically changing object. Visit Reference: Dynamically Changing IDs.
By using find_element_by_xpath
By using find_element_by_css_selector
These both will give you the same selection-point but it would be better to use Xpath which is more convenient technique. You can move forward like this;
import time
from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
driver = webdriver.Chrome('chromedriver.exe')
wait = WebDriverWait(driver, 20)
driver.maximize_window()
website_url = "http://localhost:8888/"
driver.get(website_url)
# Using Xpath
# I prefer using xpath, because it is simple to understand
# and if you want to dynamically enter data into fields, it would be an awesome approach
driver.find_element_by_xpath("//div[#id='new-buttons']").click()
if len(driver.find_elements_by_xpath("//div[#id='new-buttons']//li[#id='kernel-python3']")) > 0:
time.sleep(3)
driver.find_element_by_xpath("//div[#id='new-buttons']//li[#id='kernel-python3']").click()
driver.find_element_by_xpath('//div[#class="cell code_cell rendered selected"]').click()
# Using css_selector
#driver.find_element_by_css_selector("#notebook-container > div").click()
command = 'print("Hello World!")'
#a = driver.find_element_by_css_selector("#notebook-container > div > div.input > div.inner_cell >"
# "div.input_area > div > div:nth-child(1) > textarea")
time.sleep(3)
# To select Note-Book text-area and place command in it.
a = driver.find_element_by_xpath('//div[#class="input_area"]//textarea').click().send_keys(command)
# To run the Code in Selected Cell
time.sleep(3)
driver.find_element_by_xpath("//button[#title='Run']").click()
print("Test is done.")

Related

Selenium: Can't locate element with wait timeout set

Thanks for your time. It's a bit long, really appreciated.
I couldn't locate the element. I tried setting wait, switch frame, executing js
Here is part of the HTML DOM after the page is fully loaded: (the DOM inside iframe is omitted now)
<body class="ng1 nu-theme-neutrino nu-light-theme nu-nav-style-standard nu-responsive-mini nu-responsive-small">
<div id="display" class="flex-centered">
<div class="loading flex-centered" style="min-height: 300px">
<f-icon class="fa-loading icon-xl"></f-icon>
</div>
<iframe style="border: 0px; height: 100%; position: absolute; width: 100%;">#document</iframe>
<div class="prompt legacy-prompt">
<div class="content">
<div class="flex-column-centered">
<p>Enter your credentials</p>
<input id="user" type="text" placeholder="Username">
<input id="pass" type="password" placeholder="Password">
</div>
<div class="button-actions">
<button class="primary" type="button">Login</button>
<button type="button">Close Window</button>
</div>
</div>
</div>
</div>
<script src="/4517d062d20772b8f56b8a652474eaed/js/legacy_theme_setup.js"></script></body>
Here is what I want to achieve in python
ele = driver.find_element(By.CSS_SELECTOR, "#user")
Error:
selenium.common.exceptions.NoSuchElementException: Message: no such element:
Unable to locate element: {"method":"css selector","selector":"#user"}
Then I tried setting wait
ele = WebDriverWait(driver, 60).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "#user")))
#or
ele = WebDriverWait(driver, 60).until(EC.visibility_of_all_elements_located((By.CSS_SELECTOR, "#user")))
Both got the same output:
[22112:23972:0111/131341.033:ERROR:chrome_browser_main_extra_parts_metrics.cc(227)] START: ReportBluetoothAvailability(). If you don't see the END: message, this is crbug.com/1216328.
[22112:23972:0111/131341.033:ERROR:chrome_browser_main_extra_parts_metrics.cc(230)] END: ReportBluetoothAvailability()
[22112:23972:0111/131341.034:ERROR:chrome_browser_main_extra_parts_metrics.cc(235)] START: GetDefaultBrowser(). If you don't see the END: message, this is crbug.com/1216328.
[22112:1616:0111/131341.059:ERROR:device_event_log_impl.cc(214)] [13:13:41.059] Bluetooth: bluetooth_adapter_winrt.cc:1075 Getting Default Adapter failed.
[22112:23972:0111/131341.131:ERROR:chrome_browser_main_extra_parts_metrics.cc(239)] END: GetDefaultBrowser()
Traceback (most recent call last):
File "C:\Users\a.py", line 60, in <module>
ele = WebDriverWait(driver, 60).until(EC.element_to_be_clickable(
File "C:\Users\...\wait.py", line 89, in until
raise TimeoutException(message, screen, stacktrace)
selenium.common.exceptions.TimeoutException
It says time out, so it didn't find the element within the time limit(60s)
Then I tried locating the element in the browser js console, it succeeded.
document.getElementById('pass')
<input id=​"pass" type=​"password" placeholder=​"Password">​
document.getElementById('pass').value = '123456'
'123456'
browser js console screenshot
So I tried executing js
driver.execute_script("document.getElementById('pass').value = '123456'")
Still can't locate
Traceback (most recent call last):
File "C:\Users\a.py", line 54, in <module>
driver.execute_script("document.getElementById('pass').value = '123456'")
...
File "C:\Users\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.9_qbz5n2kfra8p0\LocalCache\local-packages\Python39\site-packages\selenium\webdriver\remote\errorhandler.py", line 247, in check_response
raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.JavascriptException: Message:
javascript error: Cannot set properties of null (setting 'value')
I also tried to locate the frame, it seems the frame was not loaded properly
DOM inside the iframe:
<html>
<head>
<style>
/* some style */
</style>
</head>
<body style="margin: 0px; padding: 0px; height: 100%; width: 100%; overflow: hidden; cursor: text; user-select: none;">
<x-screen role="textbox" tabindex="-1">
<div
style="display: block; position: fixed; overflow: hidden; user-select: text; width: 342px; height: 864px; left: 0px; top: 0px;">
<x-fold style="display: block; margin-bottom: 0px;"></x-fold>
<x-row>Server closed connection.</x-row>
<x-fold style="display: block;"></x-fold>
</div>
<div style="visibility: hidden; height: 870px;"></div><textarea tabindex="-1" contenteditable="true"></textarea>
</x-screen>
<div class="cursor-node" focus="false" title="(0, 25)"></div>
<div style="position: absolute; top: -99px; display: block; width: 10px; height: 10px;"></div>
</body>
</html>
Code:
ele = WebDriverWait(driver, 15).until(EC.frame_to_be_available_and_switch_to_it(
(By.CSS_SELECTOR, "iframe")))
print("iframe", ele)
#output: iframe True
ele = driver.find_element(By.CSS_SELECTOR, "html")
print("html", ele.get_attribute('innerHTML'))
#output: html <head></head><body></body>
ele = driver.find_element(By.CSS_SELECTOR, "div.cursor-node")
#output:no such element: Unable to locate element: {"method":"css selector","selector":"div.cursor-node"}
ele = driver.find_element(By.CSS_SELECTOR, "#pass")
#output: no such element: Unable to locate element: {"method":"css selector","selector":"#pass"}
driver.switch_to.default_content()
ele = driver.find_element(By.CSS_SELECTOR, "#pass")
#output: no such element: Unable to locate element: {"method":"css selector","selector":"#pass"}
Many thanks!
Try having a look at switch_to_frame, see:
https://selenium-python.readthedocs.io/navigating.html#moving-between-windows-and-frames
iframe = driver.find_element_by_css_selector("iframe")
driver.switch_to_frame(iframe)
elem = driver.find_element_by_css_selector("#user")
As far I can see, there is no need to switch the frame since this element is out of it.
I couldn't validate my idea, since the HTML code you placed isn't interactable.
I've modified the HTML setting up a default value in this item and it's not giving the value, however, I'm able to get the position and others values from this web element. I would advise to remove the switch method and then double check.
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Chrome('chromedriver.exe') # Optional argument, if not specified will search path.
try:
driver.get('C:\\Users\\user\\IdeaProjects\\chrome-selenium-python\\index.html')
time.sleep(2) # Let the user actually see something!
ele = driver.find_element(By.CSS_SELECTOR, "#user")
ele.send_keys("Example")
time.sleep(2)
print("Location", ele.location)
print("Tag", ele.tag_name)
except Exception as a:
print(a)
finally:
driver.quit()
wait=WebDriverWait(driver,30)
wait.until(EC.presence_of_element_located((By.ID,"id"))).send_keys('user')
Try for presence.
Imports:
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
Thank everyone for answering and trying to help me out!
I used
html = driver.page_source
print(html)
to print and see what is selenium actually seeing, and I found it was another different page. Then I realized this is another browser tab.
So I think it's solved. Thanks for your kind help

Why cant I find the element of credit card number using selenium?

I am trying to make an automated checkout system but I can't seem to send keys in fields of this payment box. Even when I try implicit wait and wait for it to load in it still doesn't work.
checkout = driver.find_element_by_id("number")
checkout.send_keys("9848432")
<input required="" autocomplete="cc-number" id="number" name="number" type="tel" aria-describedby="error-for-number tooltip-for-number" data-current-field="number" placeholder="Card number" style="font-family: Roboto, sans-serif; padding: 0.94em 0.8em; transition: padding 0.2s ease-out 0s;">
Here's a link!
Here is the URL you need to fill in the info until you get to the payment page, which is where I am having the issues
It might be in a nested iframe. A similar checkout due to not proper reproducible code.
<iframe src="https://fs.global-e.com/Checkout/v2/598d87e9-cd85-4f61-84df-81e345d62f05?gaSesID=526107767.603750114.583&gaMerchantClientInfo=undefined#undefined&chkcuid=b51f4449-13e2-4883-92ba-2641bb06ec51&isNECAllowed=true&vph=663&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: 3101px;">
<iframe id="secureWindow" class="clear-fix clearfix" allowtransparency="true" style="width: 100%; min-height: 160px; height: 165px;" src="https://securev2.global-e.com/payments/CreditCardForm/598d87e9-cd85-4f61-84df-81e345d62f05/11">
<input autocomplete="off" class="form-control input-validation-error" data-type="unknown" data-type-id="1" data-val="true" data-val-luhn="Card number not valid" data-val-luhn-allowempty="False" data-val-luhn-allowspaces="False" data-val-required="Card number" id="cardNum" name="PaymentData.cardNum" pattern="[0-9]{13,16}" placeholder="Card number" type="tel" value="">
</iframe>
</iframe>
Which was solved with:
wait = WebDriverWait(driver, 10)
wait.until(EC.frame_to_be_available_and_switch_to_it((By.ID, 'Intrnl_CO_Container')))
wait.until(EC.frame_to_be_available_and_switch_to_it((By.ID, 'secureWindow')))
checkout = wait.until(EC.presence_of_element_located((By.ID, "cardNum")))
checkout.send_keys("9848432")
Import
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

seleniumpython dropdown list div

i whould like to select the element "aout" for example on the folloing dropdown list with python selenium
<div class="questionDropdownContainer inlineBlock isActive" id="dob2_m">
<span class="questionDropdownPlaceholder" data-val="3" id="dateMonth" style="color: rgb(0, 0, 0);">mars</span>
<span class="iconDropdown inlineBlock valignMiddle"></span>
<div class="questionDropdownOptions ps-container ps-active-x ps-active-y isActiveSurveyDropDown" style="display: block; overflow: hidden;">
<span class="option-1-month" data-id="1">janvier</span>
<span class="option-1-month" data-id="2">février</span>
<span class="option-1-month selected" data-id="3">mars</span>
<span class="option-1-month" data-id="4">avril</span>
<span class="option-1-month" data-id="5">mai</span>
<span class="option-1-month" data-id="6">juin</span>
<span class="option-1-month" data-id="7">juillet</span>
<span class="option-1-month" data-id="8">août</span>
<span class="option-1-month" data-id="9">septembre</span>
<span class="option-1-month" data-id="10">octobre</span>
<span class="option-1-month" data-id="11">novembre</span>
<span class="option-1-month" data-id="12">décembre</span>
<div class="ps-scrollbar-x-rail" style="width: 120px; left: 0px; bottom: 3px;"><div class="ps-scrollbar-x" style="left: 0px; width: 110px;"></div></div><div class="ps-scrollbar-y-rail" style="top: 0px; height: 234px; right: 3px;"><div class="ps-scrollbar-y" style="top: 0px; height: 116px;"></div></div></div>
<input type="hidden" name="date_m" value="4">
</div>
When I try this code…
driver.find_element_by_id("dob2_m").click()
driver.find_element_by_id("dob2_m").find_element_by_xpath('//*[#data-id="8"]').click()
I get this error…
error script picture
How to do it ?
Help me please
Thank you
The error snippet clearly says the error occurs when webdriver tries to interact with element with class="option-1-day". But this element is not present in the code you have shared. So i assume, you are facing issue while trying to select date from dropdown.
1.Before clicking dropdown element, try to add wait statement
wait = WebDriverWait(driver, 10)
element = wait.until(EC.element_to_be_clickable((By.ID, 'someid')))
2. It will occur when the webelement you trying to click, located at end of dropdown. So it can only clickable once scrolling it down.
Actions action = new Actions(driver);
action.moveToElement(element);
Use select class for handling dropdown.
s1= Select(driver.find_element_by_id('id_of_your_element'))//in this case it would be dob2_m
s1.select_by_visible_text('janvier')
Ignore formatting using mobile to answer.
Option 2
Use javascriptexecutor to scroll and click on element
ele= self.web_driver.find_element_by_xpath('SOME_XPATH')
coordinates = ele.location_once_scrolled_into_view
self.web_driver.execute_script('window.scrollTo({}, {});'.format(coordinates['x'], coordinates
You have to use ActionChains.
When you call methods for actions on the ActionChains object, the actions are stored in a queue in the ActionChains object. When you call perform(), the events are fired in the order they are queued up.
More information.
Here is an example:
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.support.ui import Select
...#navigate to page
el=driver.find_element_by_id("bxFormPesquisa") #here I get the dropdown element
ActionChains(driver).click(el).perform()
select = Select(driver.find_element_by_name('bxFormPesquisa')) #again
select.select_by_visible_text('AL') #it is the text in dropdown list
#dropdown should be selected with value from line above

Clicking on Javascript tab using Selenium and Python without unique class id or element name

I have this HTML element code which I am currently struggling to figure out to use it for clicking on the tab that says Problem. As the "Problem" doesnt have a unique classname or element ID, I am unable to figure how to send a Click().
I have tried to check if z-index can be used as index(assumed) and used below line of code
browser.switch_to_frame(a[3])
but it seems I am wrong.
HTML code as below
<div class="TabsViewPort" style="position: relative; overflow: hidden; width: 896px; height: 22px; float: left;">
<div style="overflow: visible; float: left; width: 897px; top: 0px; left: 0px;">
<dl class="OuterOuterTab">
<dd class="OuterTab" artabid="955000038" arwindowid="0" style="top: 1px; z-index: 1; left: 0px; visibility: inherit; display: block;"><span class="TabLeftRounded"> </span>
<span class="Tab">My Profile
</span>
<span class="TabRight"> </span>
</dd>
<dd class="OuterTabSelected" artabid="600000203" arwindowid="0" style="top: 1px; z-index: 3; left: 63px; visibility: inherit; display: block;"><span class="TabLeft"> </span>
<span class="Tab">Approval
</span>
<span class="TabRight"> </span>
</dd>
<dd class="OuterTab" artabid="536870915" arwindowid="0" style="top: 1px; z-index: 1; left: 409px; visibility: inherit; display: block;"><span class="TabLeft"> </span>
<span class="Tab">Problem
</span>
<span class="TabRight"> </span>
</dd>
</dl>
</div>
</div>
The element with text as Problem is a JavaScript enabled element so to click() on the element you have to induce WebDriverWait for the element to be clickable and you can use either of the following solutions:
Using XPATH A:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//div[#class='TabsViewPort']//dl[#class='OuterOuterTab']//dd[#class='OuterTab']//a[#class='btn f1' and text()='Problem']"))).click()
Using XPATH B (shortened):
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//a[#class='btn f1' and text()='Problem']"))).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 present inside an iframe then you need to switch to iframe first to access the element.
You can Use following method to frame_to_be_available_and_switch_to_it()
By locator ID
WebDriverWait(driver,10).until(EC.frame_to_be_available_and_switch_to_it((By.ID,"id of the iframe")))
OR
By locator NAME
WebDriverWait(driver,10).until(EC.frame_to_be_available_and_switch_to_it((By.NAME,"name of the iframe")))
Once You have switched to iframe you can access the element using following xpath
To click on the element Induce WebDriverWait and element_to_be_clickable()
WebDriverWait(driver,10).until(EC.element_to_be_clickable((By.XPATH,"//span[#class='Tab']//a[text()='Problem']"))).click()
You need to import following to execute above code.
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
Hope this will help.
please find below xpath to click on third TAB
(//span[#class="Tab"])[3]/a

How to locate the upload button related to the text Upload Image as per the HTML?

I'm using Selenium with Firefox (I've tried chrome but the success ratio on this one was significantly lower). I'm trying to locate an element (upload button) and the success ratio is nowhere near an acceptable percentage.
Now I know that I could try to use just selenium to the input but it wont locate it as well no matter what I do. So I used AutoIt for the uploading part.
frdriver.get('')
time.sleep(11)
try:
# el = WebDriverWait(frdriver, 15).until(EC.presence_of_element_located((By.XPATH, '/html/body/div[1]/header/div[2]/div[2]/div/div/form/i[2]')))
el = frdriver.find_element_by_xpath('/html/body/div[1]/header/div[2]/div[2]/div/div/form/i[2]')
try:
el.click()
print(el)
#ActionChains(frdriver).move_to_element(el).click().perform()
try:
#element = WebDriverWait(frdriver, 15).until(EC.presence_of_element_located((By.XPATH, '/html/body/div[1]/header/div[2]/div[2]/div/div/form/div[2]/div[3]/div[1]/div/div/div[1]')))
element = frdriver.find_element_by_xpath('/html/body/div[1]/header/div[2]/div[2]/div/div/form/div[2]/div[3]/div[1]/div/div/div[1]')
time.sleep(4)
try:
element.click()
#ActionChains(frdriver).move_to_element(element).click().perform()
autoit.run("/image.exe")
r = 100
except:
print('Firefox retries upload')
r += 1
except:
print('Firefox retries upload')
r += 1
except:
print('Firefox retries upload')
r += 1
except:
print('Firefox retries upload')
r += 1
As you can see I've tried many ways, each one had almost the same success.
I'm using a remote windows machine for the job and it really might be my idea, but when it isn't minimized it works a lot better.
Also there is something else, for some reason there are times that even if it hasn't successfully clicked a button it bypasses the try/except and proceeds.
Edit html of the page
<div class="ui-searchbar-keyword-panel ui-searchbar-keyword-hide ui-searchbar-static" style="z-index: 99; position: absolute; left: 0px; top: 35px;" data-widget-cid="widget-7">
<div class="ui-searchbar-img-search-box">
<div class="icbu-w-image-uploader-panel">
<div class="icbu-w-image-uploader-content">
<div class="upload-btn-wrapper">
<div class="upload-btn" data-spm-anchor-id="a2700.8293689.scGlobalHomeHeader.i1.2ce265aarlKA3D" style="z-index: 1;">Upload Image</div>
<div id="html5_1cjiqdvveht51pom1nbkqoiaop3_container" class="moxie-shim moxie-shim-html5" style="position: absolute; top: 14px; left: 224px; width: 109px; height: 28px; overflow: hidden; z-index: 0;">
<input id="html5_1cjiqdvveht51pom1nbkqoiaop3" type="file" style="font-size: 999px; opacity: 0; position: absolute; top: 0px; left: 0px; width: 100%; height: 100%;" multiple="" accept="image/jpeg,image/png,image/bmp">
</div>
</div>
<div class="response-text">Max 2MB per Image</div>
</div>
</div>
</div>
<div class="J-box-loadding-mask box-loadding-mask" data-role="loading" style="display: none;">
<div class="mh-mamo-loadding-box">
<i class="mh-mamo-icon-loadding"></i>
<span class="J-loading-text mh-mamo-loadding-text">Loading...</span>
</div>
</div>
</div>
You should use driver.implicitly_wait(X) where X is a number of seconds instead of reinventing the wheel with using time.sleep and retrying. That will increase selenium's tolerance towards the page loading and you will have better success in finding page elements.
To locate the upload button related to the text Upload Image you can use the following solution:
XPATH:
upload_button = WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//div[#class='upload-btn-wrapper']//div[#class='moxie-shim moxie-shim-html5' and starts-with(#id,'html5_')]/input[starts-with(#id,'html5_')]"))).click()
CSS_SELECTOR:
upload_button = WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "div.upload-btn-wrapper div.moxie-shim.moxie-shim-html5[id^='html5_']>input[id^='html5_']"))).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

Categories

Resources