I am trying to select all the text in a textbox in order to clear the textbox. I am using Ctrl+A to do this using the following Python 2.7 code on Selenium RC standalone 2.20.0.jar Server on Windows 7 firefox:
from selenium import selenium
s = selenium('remote-machine-ip', 4444, '*chrome', 'http://my-website-with-textbox')
locator = 'mylocator-of-textbox'
s.open()
s.type(locator, 'mytext')
s.focus(locator)
s.control_key_down()
s.key_down(locator, "A")
s.key_press(locator, "A")
s.key_up(locator, "A")
s.control_key_up()
# Nothing happens here... I cannot see the text getting selected...
# Nothing gets cleared here except the last char
s.key_down(locator, chr(8)) # Pressing backspace
s.key_press(locator, chr(8))
s.key_up(locator, chr(8))
Any help?
Thanks,
Amit
I'm using clear() in WebDriver without any hassle...
el = self.selenium.find_element_by_name(name)
el.clear()
In Selenium RC, simply use the following to clear a textbox
selenium.type("someLocator", "");
Try using first
element.click()
then use element
element.clear()
It might solve your issue as it really solved mine.
You can do this:
public void selectAll(WebElement element) {
String selectAll = Keys.chord(Keys.CONTROL, "a");
element.sendKeys(selectAll);
}
And when you whant to use it, for example:
selectAll(myDriver.findElement(By.id("testId")));
In this example the WebElement can be a text box, text area and similars.
Related
This problem is driving me insane: I'm trying to capture the response from a Pandorabot using Selenium but although I can input text and make the bot reply, its webpage is formatted in such a way that makes selecting the output text a nightmare.
This is my code in Python:
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from time import sleep
driver = webdriver.Firefox()
driver.get("http://demo.vhost.pandorabots.com/pandora/talk?botid=b0dafd24ee35a477")
elem = driver.find_element_by_name("input")
elem.clear()
elem.send_keys("hello")
elem.send_keys(Keys.RETURN)
line = driver.find_element_by_xpath("(//input)[#name='botcust2']/preceding::font[1]/*")
print(line)
response = line.text
print(response)
driver.close()
which manages to get the first bit of the response ("Chomsky:") but not the rest.
How do I get to properly capture the response text (ideally excluding the bot name)?
Is there a more elegant way to do it (eg jquery script) that wouldn't break so easily if the webpage gets reformatted?
Many thanks!
Edit
So, after playing around a bit more with jQuery I found a workaround to the problem of any URL text not showing.
I set the whole text string into a variable and then I replace any instances of the name and empty lines with ''. So the jQuery code as pointed out by pguardiario becomes:
# get the last child text node
response = self.browser.execute_script("""
var main_str = $('font:has(b:contains("Chomsky:"))').contents().has( "br" ).last().text().trim();
main_str = main_str.replace(/Chomsky:/g,'').replace(/^\\s*[\\r\\n]/gm, '');
return main_str;
""")
I'm sure there may be better/more elegant ways to do the whole thing but for now it works.
Many thanks to pguardiario and everyone else for the suggestions!
Since you asked for jQuery:
from requests import get
body = get("http://code.jquery.com/jquery-1.11.3.min.js").content.decode('utf8')
driver.execute_script(body)
# get the last child text node
response = driver.execute_script("""
return $('font:has(b:contains("Chomsky:"))').contents().last().text().trim()
""")
To capture the response from a Pandorabot using Selenium as the response is within a text node you can execute_script() method as follows:
Code Block:
driver.get('http://demo.vhost.pandorabots.com/pandora/talk?botid=b0dafd24ee35a477')
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "input[name='input']"))).send_keys("hello")
driver.find_element_by_css_selector("input[value='Ask Chomsky']").click()
print(driver.execute_script("return arguments[0].lastChild.textContent;", WebDriverWait(driver, 20).until(EC.visibility_of_element_located((By.XPATH, "//input[#value='Ask Chomsky']//following-sibling::font[last()]//font")))).strip())
Console Output:
Hi! Can I ask you a question?
I'm using Selenium with Python and Firefox on Windows 7.
Running through my script, at some point Selenium can't find any elements beside and after I navigated to a certain part of a website.
The website belongs to an E-Mail provider called freemail (https://web.de/). I have set up a test account to complete a training project from chapter 11 of the book "Automate the Boring Stuff with Python".
Python, Selenium and Firefox are all up to date. And before this certain part of the website everything was working fine (including finding tags, class names, id's etc.).
I tried like 10 different ways to click one of the ways to navigate to the inbox of the E-Mail provider but had no luck in making it work.
Here is the HTMLcode with the highlighted element I want Selenium to click.
Here another image of the Website itself with the button highlighted in the upper left corner.
And this is the code for my script:
## This program navigates through the website of an
## e-mail provider and sends a mail automatically.
# Import necessary modules
from selenium import webdriver
# Mail account info
mailLink = 'https://web.de/'
mailAddress = 'testing2772#web.de' # This is just a test account
mailPw = 'ewaa11ewaa11'
# Recipient % content of the e-mail
recipient = 'pradicradr#matra.top'
mailContent = 'Test this awesome string.'
# Set up browser
browser = webdriver.Firefox()
browser.get(mailLink)
# Log into account
browser.find_element_by_class_name('icon-freemail').click()
browser.find_element_by_id('freemailLoginUsername').send_keys(mailAddress)
pwElem = browser.find_element_by_id('freemailLoginPassword')
pwElem.send_keys(mailPw)
pwElem.submit()
# Close notification overlay if it pops up
try:
browser.find_element_by_class_name('layerCloser').click()
except:
pass
## At this point Selenium can't Find 99% of elements including the one I need
## Testing if Selenium finds basic elements
testElem1 = browser.find_element_by_tag_name('html') # works
testElem2 = browser.find_element_by_tag_name('body') # works
testElem3 = browser.find_element_by_tag_name('div') # works
## Click link to inbox (all of these variants won't work somehow)
linkToInbox = browser.find_element_by_class_name('nx-track-sec-click-communication-newmail') # try by class_name
linkToInbox = browser.find_element_by_xpath("/html/body/div[3]/div/div[3]/div[1]/ul/li[3]/a") # try by XPath
linkToInbox = browser.find_element_by_link_text('E-Mail schreiben') # try by link_text
linkToInbox = browser.find_element_by_css_selector('a.nx-track-sec-click-communication-newmail') # try by CSS selector
linkToInbox = browser.find_element_by_css_selector('a.newmail') # try by CSS selector
linkToInbox = browser.find_element_by_css_selector('a.nx-track nx-track-sec-click-communication-newmail newmail') # another try by CSS selector
linkToInbox = browser.find_element_by_css_selector('a[title="E-Mail schreiben"]') # another try by CSS selector
## TODO: Click link to write a new mail
## TODO: Fill in recipient and mail content
## TODO: Send mail and close program
I guess it has something to do with an iframe? But I'm a beginner and I don't know how to handle this :/
Thanks in advance!
EDIT:
I solved the problem by finding another button that linked to the inbox with
browser.find_element_by_xpath("/html/body/atlas-app/atl-navbar/atl-actions-menu/div[1]/div[1]/atl-menu-item[2]/pos-icon-item/span/span").click(). This button is not within an iframe, so no problem here.
However, it is still strange that I can't enter any iframes. Here is another image to make it more clear. Does anybody know how to switch to that iframe?
browser.switch_to.default_content() and then browser.switch_to.frame('home') doesn't do the trick...
SECOND EDIT:
KunduK's answer did it.
The problem was, that the script needs to wait for the iframe to become available and then for the button to become available after that. See his post further down for the exact approach. Thanks everyone!
To click on the E-Mail schreiben link you need to switched to iframe first and then click on link.Use WebDriverWait and frame_to_be_available_and_switch_to_it and then use element_to_be_clickable
WebDriverWait(browser,20).until(EC.frame_to_be_available_and_switch_to_it((By.NAME,'home')))
WebDriverWait(browser,10).until(EC.element_to_be_clickable((By.XPATH,'//div[#id="navigation"]//ul//li[#class="item"]//a[#title="E-Mail schreiben"]'))).click()
You need to use following imports 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
I guess it has something to do with an iframe?
Since the elements you are trying to find are in an iframe, you must first switch to the iframe before finding the elements. Your iframe has a name=home attribute, so you should be able to add:
driver.switch_to.frame('home')
... then find the elements.
Once you are done interacting with the iframe and want to switch back to the top level content, use:
driver.switch_to.default_content()
Option 1
linkToInbox = browser.find_element_by_css_selector('a.nx-track.nx-track-sec-click-communication-newmail.newmail') # try by CSS selector
Option 2
use the title property of the anchor link
linkToInbox = browser.find_element_by_css_selector('a[title="E-Mail schreiben"]')
option 3
re-read the docs: https://selenium-python.readthedocs.io/locating-elements.html
I want to open 'text' botton but I can't open it.
How can I do?
from selenium import webdriver
import time
driver = webdriver.Chrome(path)
driver.get("https://www.pdfescape.com/account/unregistered/")
time.sleep(0.5)
elem = driver.find_element_by_id("dStartNew").click()
time.sleep(0.5)
elem = driver.find_element_by_id("PdfNew_input_pc").click()
driver.find_element_by_css_selector("[value=\"2\"]").click()
#time.sleep(0.5)
elem = driver.find_element_by_id("PdfNew_input_ps").click()
driver.find_element_by_css_selector("[value=\"a4\"]").click()
#time.sleep(0.5)
driver.find_element_by_xpath('//*[#id="PdfNew_form"]/input[1]').click()
time.sleep(0.5)
driver.find_elements_by_class_name('Add-Text').click()
Problem code : driver.find_elements_by_class_name('Add-Text').click()
The element you wanted to click has no class name - it has the title "Add Text", also you are using find_elements instead of find_element which changes the result type.
So you could select it with:
driver.find_element_by_css_selector('a[title=\"Add Text\"]').click()
Also please let me add another improvement:
driver.find_element_by_xpath('//*[#id="PdfNew_form"]/input[1]').click()
could be much more stable (for the case of page changes) written as:
driver.find_element_by_css_selector('input[type=\"submit\"]').click()
driver.find_elements_by_class_name('Add-Text'),click()
Above code should return a list of elements and you can not click on list of elements
This element is not present in the DOM
To click we use '.' instead of ','
I would like to send a :heart: emoji with selenium's send_keys()
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
driver = webdriver.Chrome('./chromedriver')
driver.get("https://web.whatsapp.com/")
wait = WebDriverWait(driver, 600)
message = driver.find_elements_by_xpath('//*[#id="main"]/footer/div[1]/div[2]/div/div[2]')[0]
message.send_keys(":heart:")
However, this does not work and sends a string ':heart:'.
Could you please suggest how to do it correctly?
Well,
Here is a workaround! Hope it works!
text_element = driver_trader.find_element_by_xpath('xpath')
text = '⚪📢😆'
driver.execute_script("arguments[0].innerHTML = '{}'".format(text),text_element)
text_element .send_keys('.')
text_element .send_keys(Keys.BACKSPACE)
Here is a tricky way. we can take help of JavaScript and then driver.execute_script that JS code. You can use this function to do that:
from selenium import webdriver
from selenium.webdriver.common.by import By
import chromedriver_autoinstaller
chromedriver_autoinstaller.install()
driver = webdriver.Chrome()
def paste_content(driver, el, content):
driver.execute_script(
f'''
const text = `{content}`;
const dataTransfer = new DataTransfer();
dataTransfer.setData('text', text);
const event = new ClipboardEvent('paste', {{
clipboardData: dataTransfer,
bubbles: true
}});
arguments[0].dispatchEvent(event)
''',
el)
# Go to a page
driver.get('https://some-random-site-as-you-wish.com')
# Find the input box
input_el = driver.find_element(By.XPATH, '//some-xpath')
msg = 'Done! 😈 💯'
paste_content(driver, input_el, msg)
You can not do it directly. You need to do this via javascript.
Once Javascript has been formatted properly, you need to notify listeners.
Before that, you need to find the unicode of any emoji you want to use.
To get codepoint of any emoji, this website can be used:
https://emojipedia.org/
Search for any emoji and at the bottom of the page, there will be the codepoint for it.
To convert codepoint to unicode for javascript, use following website:
https://r12a.github.io/app-conversion/
Type the codepoint and copy the value in javascript box of it.
Once, you have it, use JavaScript as follows:
JS_ADD_TEXT_TO_INPUT = """
var elm = arguments[0], txt = arguments[1];
elm.value += txt;
elm.dispatchEvent(new Event('change'));
"""
elem = driver.find_element_by_id('<Id of your webelement>')
text = u'\u2764'
driver.execute_script(JS_ADD_TEXT_TO_INPUT, elem, text)
2764 is unicode for heart emoji.
Hope this helps for any kind of emoticons you want to insert to your whatsapp!
Edit: For more complex emoticons:
You need to add multiple unicodes like
Emoji for family : 👪
\uD83D\uDC6A
guys.
I found a really simple but powerfull way to add emoji to whatsApp using Selenium
Message_box.send_keys(':emoji' u'\ue007') # You just have to enter the code cording to the next page
https://gist.github.com/hkan/264423ab0ee720efb55e05a0f5f90887
Copy the emoji to clipboard and paste in the input element will work too.
mch22, men your trick is awesome! thank you very much.
just in case someone is wondering how to do a line break inside the text, you can use labels within the text like this:
text = '⚪<br>📢<br>😆'
punctures perfect for my whatsapp bot!
i'm using selenium 2.46.0 and python 3.4
I want to put the string "Hello, world!" into the textfield for creating new letter.
Am i doing this the right way? I try to switch the frame and find the right element to put the text into it.
My code:
from selenium import webdriver
browser = webdriver.Firefox()
browser.get('https://mail.ru/')
browser.find_element_by_name('Login').clear()
browser.find_element_by_name('Login').send_keys('selenium90')
browser.find_element_by_name('Password').clear()
browser.find_element_by_name('Password').send_keys('pythonrocks')
browser.find_element_by_id('mailbox__auth__button').click()
browser.find_element_by_css_selector('a.b-toolbar__btn').click()
browser.find_element_by_css_selector('textarea.js-input:nth-child(5)').send_keys('07ufo#mail.ru')
browser.switch_to_frame(browser.find_element_by_id('compose_462_composeEditor_ifr'))
browser.find_element_by_class_name('mceContentBody').send_keys('Hello, world!')
selenium.common.exceptions.NoSuchElement
Exception: Message: Unable to locate element: {"method":"id","selector":"compose_462_composeEditor_ifr"}
I tried:
iframe = browser.find_elements_by_tag_name('iframe')[frameindex]
browser.switch_to_frame(iframe)
browser.find_element_by_css_selector('body.tinymce').send_keys('hoo')
But it did not help
i added a screenshot of tree:
The id of that element is dynamically generated! Try something like:
browser.switch_to_frame(browser.find_element_by_xpath('//frame[contains(#id, "composeEditor_ifr")]'))