I am writing a program to gather data from a website, however at some point in the program I need to enter an email and password into text boxes. The route I am attempting to go is to use driver.execute_script to change the underlying HTML, however I am having difficulty connecting that command with the XPATH value that I use to find the element. I know there are a few threads on here that deal with similar issues, however I have been completely unable to find one that uses XPATH. Any help would be greatly appreciated as I am totally stuck here.
Below is the line of HTML that I am attempting to change, as well as the XPATH value associated with the text box.
XPATH Value
/html/body/center/div[4]/table[2]/tbody/tr/td[4]/table[1]/tbody/tr[2]/td/table/tbody/tr[7]/td[2]/font
HTML:
<input onclick="if (this.value == 'Enter Your Name') this.value='';" onchange="if (this.value == 'Enter Your Name') this.value='';" name="name" type="text" value="Enter Your Name" style="padding-top: 2px; padding-bottom: 6px; padding-left: 4px; padding-right: 4px; width:120px; height:15px; font-size:13px; color: #000000; font-family:Trebuchet MS; background:#FFFFFF; border:1px solid #000000;">
I am attempting to replace value = "Enter Your Name" with value = "Andrew" - or any other name for that matter. Thank you very much for any and all advice, and please let me know there is any additional data / info that is required.
Send_Keys scripts:
name = driver.find_element_by_xpath('//body/center/form/span/table/tbody/tr/td[1]/input')
name.clear()
name.send_keys("Andrew")
Your <input> tag is contained within an <iframe>, so you'll need to switch the context to the <iframe> first:
driver.switch_to.frame(driver.find_element_by_tag_name("iframe"))
Now that you're "inside" the <iframe>, your send_keys script should work:
name = driver.find_element_by_xpath('//body/center/form/span/table/tbody/tr/td[1]/input')
name.clear()
name.send_keys("Andrew")
Lastly, here's how to switch back to the default content (out of the <iframe>):
driver.switch_to.default_content()
Related
I am trying to automate some tasks at work. Requests wont work because I don't have admin access to my works Intercom App. Therefore I use Selenium.
I want to write "Hey" in the chat box of Intercom, and send the message.
** The problem is a changing ember number every time I have a new conversation. It works when I copy the right ember number every time, but when changing the conversation, it doesn't work anymore. **
I am looking for some kind of script to change the ember = XXXXX into the right number each time
Not really relevant to the code problem, but I am using Chrome in debugging mode, to avoid logging in every time I need to test the code, and I am using tkinter to have a button to press, every time I want to write "Hey" in the chat box.
Sorry, I understand it is difficult to replicate this problem.
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
#___________
#In order to run Selenium in an already opened browser / session, I need to run this code in CMD:
#cd C:\Program Files (x86)\Google\Chrome\Application
#
#chrome.exe --remote-debugging-port=9222 --user-data-dir="C:\Users\peter\testprogram"
#___________
opt=Options()
opt.add_experimental_option("debuggerAddress","localhost:9222")
driver=webdriver.Chrome(executable_path="
C:\\ProgramFiles\\crromedriver\\chromedriver.exe",options=opt)
def hey():
ember = 32890
hey = driver.find_element_by_xpath('//*[#id="ember'+str(ember)+'"]/div/div[3]/div[1]/div/p')
hey.send_keys("Hey!")
The specific HTML element where I want to write "Hey!": (This is under the big HTML code below)
<p class="intercom-interblocks-align-left embercom-prosemirror-composer-block-selected" style="">Hey! This is where I want my text</p>
One might suggest to use
hey = driver.find_element_by_class_name('intercom-interblocks-align-left embercom-prosemirror-composer-block-selected')
hey.send_keys("Hey!")
But this doesn't work for me.
The HTML element where the ember number is changing:
<div id="ember32890" class="u__relative inbox__conversation-composer__wrapper ember-view"><div>
<div></div>
<div>
</div>
<div data-test-prosemirror-composer="" class="composer-inbox composer-style-basic o__fit conversation__text embercom-prosemirror-composer ">
<style>
.ProseMirror {
outline: none;
white-space: pre-wrap;
}
.ProseMirror .intercom-interblocks-html-block {
white-space: normal;
}
li.ProseMirror-selectednode {
outline: none;
}
.ProseMirror-selectednode.embercom-prosemirror-composer-image img,
.ProseMirror-selectednode.embercom-prosemirror-composer-video iframe,
.ProseMirror-selectednode.embercom-prosemirror-composer-messenger-card
.intercom-interblocks-messenger-card,
.ProseMirror-selectednode.embercom-prosemirror-composer-html-block,
.ProseMirror-selectednode.embercom-prosemirror-composer-button .intercom-h2b-button {
outline: 2px solid #8cf;
}
hr.ProseMirror-selectednode,
.embercom-prosemirror-composer-template.ProseMirror-selectednode,
.embercom-prosemirror-composer-mention.ProseMirror-selectednode {
outline: 1px solid #8cf;
}
</style>
<div>
<!----><div contenteditable="true" role="textbox" dir="auto" data-insertable="true" class="ProseMirror embercom-prosemirror-composer-editor dir-auto"><p class="intercom-interblocks-align-left embercom-prosemirror-composer-block-selected" style="">Hey!Hey!Hey!Hey!Hey!</p><p class="intercom-interblocks-align-left" style=""><br></p></div></div>
<div class="flex flex-row flex-wrap gap-4 embercom-prosemirror-composer-attachment-list">
<!----></div>
<!---->
<!---->
<!---->
<!---->
<!---->
<div></div>
<!---->
<!----></div>
<!---->
<!----></div></div>
If you want to use ember here is a possible solution:
hey = driver.find_element_by_xpath('//*[contains(#id="ember")]/div/div[3]/div[1]/div/p')
hey.send_keys("Hey!")
This will probably fail if there are multiple elements with id="ember[0-9]+".
If you want to access the p tag directly use find_element_by_css_selector, like so:
hey = driver.find_element_by_css_selector('.intercom-interblocks-align-left.embercom-prosemirror-composer-block-selected')
hey.send_keys("Hey!")
Your code with find_element_by_class_name did not work because it's expecting one class name and you are passing two class names (class names are separated by space).
Friends facing challenges again in following scenarios using Python with Selenium web driver:-
Click event not happening on clicking the link name as "Area Rank Web".
HTML Code for MSTR Report is as follows:-
<td class="mstrLargeIconViewItemText" rowspan="1" colspan="1" cx="[2,1,0,5,1,6,7]" cxid="folderAllModes_cmm" oid="600E4BA841AC84797221F7BB5262C3E0" oty="55"><a title="Run Document" class="mstrLargeIconViewItemLink" onclick="return submitLink(this, event);" href="Main.aspx?evt=2048001&src=Main.aspx.2048001&visMode=0¤tViewMedia=1&documentID=600E4BA841AC84797221F7BB5262C3E0" runasexpress="1" alt="Run Document"></a><div class="mstrLargeIconViewItemName"><span sty="nm"><a title="Area Rank Web" class="mstrLink" onclick="return submitLink(this, event);" href="Main.aspx?evt=2048001&src=Main.aspx.2048001&visMode=0¤tViewMedia=1&documentID=600E4BA841AC84797221F7BB5262C3E0" runasexpress="1">Area Rank Web</a></span></div><div class="mstrLargeIconViewItemOwner"><label>Owner:</label><span><div title="Administrator" class="owner">Administrator</div></span></div><div class="mstrLargeIconViewItemModified"><label>Modified:</label><span><div timestamp="1525148536000">5/1/18 4:22:16 AM</div></span></div><div class="mstrLargeIconViewItemDescription"></div><div></div><div class="mstrLargeIconViewItemActions"><span><a class="mstrLink" onclick="if (!mstrFolderActions.checkACL(this, event, '600E4BA841AC84797221F7BB5262C3E0', 55)) return; return submitLink(this, event);" href="Main.aspx?evt=3032&src=Main.aspx.3032&objectType_3032=55&objectID_3032=600E4BA841AC84797221F7BB5262C3E0" ty="sub">Subscriptions</a></span></div></td>
I tried following ways but not getting success:
#driver.find_element_by_xpath(".//*[title='Area Rank Web']").click();
#driver.find_elements_by_class_name (("mstrLargeIconViewItemName") and contains(.,'Area Rank Web')).click()
#driver.find_element_by_id("600E4BA841AC84797221F7BB5262C3E0").click()
#driver.find_element_by_css_selector("600E4BA841AC84797221F7BB5262C3E0").click()
#WebDriverWait(driver, 5).until(EC.element_to_be_clickable((By.XPATH, "//div[#class='mstrLargeIconViewItemText']/span[#class='mstrIcon-lg' and contains(.,'Area Rank Web')]"))).click()
2.
There is a block having two values as:- AREA, DISTRICT. You can select more than value and then click on arrow button which moves selected content to the right side of block and then click on submit button
HTML code:
<div title="AREA" class="mstrListBlockItemSelected" style="margin-top: 0px;"><div class="mstrBGIcon_ae mstrListBlockItemName" style="background-position: 2px 50%; padding-left: 23px;">DSI</div></div>
<div title="DISTRICT" class="mstrListBlockItem" style="margin-top: 0px;"><div class="mstrBGIcon_ae mstrListBlockItemName" style="background-position: 2px 50%; padding-left: 23px;">ONC</div></div>
Tried following ways but click event is not happening
Can you try link_text/ partial_link_text instead?
driver.find_element_by_link_text('Area Rank Web').click()
OR
driver.find_element_by_partial_link_text('Area Rank Web').click()
Also, try having an explicit wait before you click on the link.
WebDriverWait(self.driver, 10).until(expected_conditions.element_to_be_clickable(
(By.LINK_TEXT, 'Area Rank Web')
))
if all the above fails, use execute_script method to invoke a click event on the link
link = driver.find_element_by_link_text('Area Rank Web')
driver.execute_script('arguments[0].click();', link)
I'm getting TimeoutException when using this code to get the fill in the CardNum textbox with a number
CardNUM = WebDriverWait(browser, 10).until(EC.presence_of_element_located((By.XPATH, '//*[#id="number"]')))
CardNUM.send_keys(cardNum)
Xpath is taken directly from right clicking and inspecting the textbox and copying the XPATH for the block
<input autocomplete="cc-number" id="number" name="number" type="tel" aria-describedby="error-for-number" data-current-field="number" class="input-placeholder-color--lvl-30" placeholder="Card number" style="color: rgb(151, 151, 151); font-family: "Helvetica Neue"; padding: 0.94em 0.8em; transition: padding 0.2s ease-out;">
Is there something else I need to do to be able to fill in the box, for example is the text box hidden and is there some manipulation that I would need to do beforehand to be able to find the text box?
Most likely the element is inside an IFRAME, especially since it seems to be a credit card number. The payment portion of payment pages are typically in an IFRAME for security. Try switching to the IFRAME first then your code should work.
I'm trying to automate some processes at work on our inventory site and I'm having trouble inputing text into a simple search box!
Here is the website code:
<td class="GJCH5BMASD" style="">
<input type="text" class="GJCH5BMD1C GJCH5BME1C" style="font-size: 13px; width: 100%;">
</td>
Here is my code:
opens = driver.find_element_by_css_selector(".GJCH5BMD1C GJCH5BME1C").click()
I keep receiving the error:
ElementNotVisibleException: Cannot click on element
Any thoughts?
Well nevermind!
I fixed it by changing:
opens = driver.find_element_by_css_selector(".GJCH5BMD1C GJCH5BME1C").click()
to:
opens = driver.find_element_by_css_selector(".GJCH5BMASD").click()
You need to provide . with every class name using css_selector, you can also try as below :-
opens = driver.find_element_by_css_selector(".GJCH5BMD1C.GJCH5BME1C").click()
I have been trying to locate an element on a web page, this element has the same name as other elements and no id. It does have a different value, so I would like to find the element by the name AND the Value.
in my web page I have a search button:
<input name="action" value=" Search " style=" border-style2; font-size: 11;
font-family: arial, helvetica" border="0" type="submit">
I can't use name because I have another element with the same name and type:
<input name="action" value=" Go " onclick=" return custRange('cust', 'd_custno');"
style=" border-style2; font-size: 11; font-family: arial, helvetica"
border="0" type="submit">
I therefore tried to use xpath, I started by using the xpath checker to return the xpath which returned:
/x:html/x:body/x:center/x:table/x:tbody/x:tr/x:td/x:center/x:center[1]/x:table[2]/x:tbody/x:tr/x:td[1]/x:table[3]/x:tbody/x:tr[5]/x:td[2]/x:input[2]
Again pretty new to this but I'm assuming the "x:" shouldn't be in the path so I removed this and tried to find the element with the following:
search = driver.find_element_by_xpath("//center[1]/table[2]/tbody/tr/td[1]/table[3]/tbody/tr[5]/td[2]/input[2]")
search.clickAndWait()
which resulted in:
selenium.common.exceptions.NoSuchElementException: Message: 'Unable to find element with xpath == //center[1]/table[2]/tbody/tr/td[1]/table[3]/tbody/tr[5]/td[2]/input[2]'
So really I have 2 questions it would be great if someone could help with:
is there a way to identify an element by name and value?
obviously I'm missing something with xpath, is the way I'm trying to use xpath incorrect? if so could you suggest what I'm doing wrong?
Any help greatly appreciated.
for completeness my unittest code is is as follows:
import unittest
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
class umLoginTest(unittest.TestCase):
def setUp(self):
self.driver = webdriver.Ie()
self.driver.implicitly_wait(3)
def test_login_to_um(self):
driver = self.driver
result_file = open("umLoginTest_result.txt", "w")
driver.get("http://ps-iweb/UserManage/Home")
self.assertIn("Welcome", driver.title)
elem = driver.find_element_by_name("userLogin")
elem.send_keys("pstevenson")
password = driver.find_element_by_name("sec_password")
password.send_keys("etc")
password.send_keys(Keys.RETURN)
test1 = driver.title
result_file.write(str(test1))
select = driver.find_element_by_name("conn_marketid")
for option in select.find_elements_by_tag_name('option'):
if option.text == 'Int Rate Swaps':
option.click()
search = driver.find_element_by_xpath("//center[1]/table[2]/tbody/tr/td[1]/table[3]/tbody/tr[5]/td[2]/input[2]")
search.clickAndWait()
result_file.close()
if __name__ == "__main__":
unittest.main()
Try this
//input[#name='action' and #value=' Search ']
Answering your questions,
1 - Yes you can,
driver.find_element_by_name(‘foo’)
http://selenium-python.readthedocs.org/en/latest/api.html#selenium.webdriver.remote.webdriver.WebDriver.find_element_by_name
2 - I always try to avoid xpath because sometimes it doesn't work properly. Instead, you should always try to find by name or id .. I think is the best case.
Following is the Java code, which i tried with your 2 controls specified above.
driver= new FirefoxDriver();
driver.get("file:///D:/Programming%20Samples/Input.html");
driver.findElement(By.xpath("//*[#name='action'][#value='Go']")).click();
driver.findElement(By.xpath("//*[#name='action'][#value='Search']")).click(); //observed here in your HTML i see some spaces. Make sure giving the right value.
Hope above helps.
driver.find_element_by_xpath("//*[#value=' Search ']").click()
will definitely help.