Python, Selenium - Can not find element inside IFRAME even after switching - python

I am trying to get the value form an input field that is in an iframe. I switched to the iframe but the program is still unable to find the element, so a time out exception is raised. I am using the internet explorer web driver and I can not use any other driver because the website only works in internet explorer.
The code I use:
browser = webdriver.Ie()
browser.get('http://www.thewebsite.com')
wait = WebDriverWait(browser, 10)
wait.until(EC.frame_to_be_available_and_switch_to_it((By.ID, 'Content')))
MRR = wait.until(EC.element_to_be_clickable((By.XPATH, "//INPUT[#id='txtTotalMonthlyCharge']"))).get_attribute('value')
I already tried increasing the wait time and also locationg by ID
The HTML:
<iframe id="Content">
<html>
<head>
</head>
<body style="margin-left: 0; margin-top: 0; overflow:hidden">
<form name="frmServicesTree" method="post" action="ServicesTree.aspx?AccountNo=50084779&pageID=SERVICESTREE" id="frmServicesTree">
<table>
<tr>
<td class="flowLabel" width="140px"><span id="txtTotalMonthlyChargelabel" style="width:95%;height:17px;">Total Monthly Charge</span></td><td class="flowReadOnly"><input name="txtTotalMonthlyCharge" id="txtTotalMonthlyCharge" type="text" readonly="" tabindex="-1" value="JA$11,199.00" style="vertical-align:top;width:100%;" /></td>
</tr>
</table>
</body>
</iframe>

Related

How to click an element using Selenium and Python

I have a problem with clicking an element using XPath in selenium. Here is the HTML element for the problem :
<label for="file" class="pb default" style="display: inline-block;margin: 5px 10px;">Select File</label>
Do you know the solution for this? Any response is really appreciated.
UPDATE :
here is the whole source code for the problem
<html>
<head>
<META http-equiv="Content-Type" content="text/html; charset=utf-8">
<BASE HREF="http://1.1.1.19/webclient/utility">
<link rel=stylesheet type="text/css" href="../webclient/skins/skins-20190807-1904/iot18/css/filex.css">
</head>
<body style="background: transparent; background-color: transparent">
<form name="IMPORT" id="IMPORT" enctype="multipart/form-data" method="post">
<input type="hidden" NAME="componetId" VALUE="itemimage_3_1-if">
<input type="hidden" NAME="controlId" VALUE="itemimage_3_1">
<table width="100%" cellspacing="0" align="center" class="maintable">
<tr>
<td align="left" style="white-space: nowrap;">
<label for="file" class="pb default" style="display: inline-block;margin: 5px 10px;">Select File</label>
<input id="fileName" onmousedown="" type="text" value="" class="fld fld_ro text ib" readonly size="50"/>
<input id="file" type="file" name="value" title="Specify a New File" onchange="" size="35" class="text" style=" width: 0.1px;height: 0.1px !important;fileStyle: 0;overflow: hidden;position: absolute;z-index: -1;opacity: 0;" value="" onclick="if(!parent.undef(parent.firingControl) && parent.firingControl.id==this.id){parent.sendEvent('clientonly','clickFileButton', this.id)}">
</td>
</tr>
</table>
</form>
</body>
<script>
document.querySelector('#file').addEventListener('change', function(e){
document.querySelector('#fileName').value = e.currentTarget.files[0].name;
});
</script>
</html>
Can try with //label[#for='file'] or //label[#for='file'][text()='Select File']
If this is not working maybe you are targeting the wrong element or you are not waiting enough before it appears. When dealing with uploading files, I target the input with type file //input[#type='file'], not the label, you may need to provide bigger part of your HTML.
if class=pb default is a unique class in the web-page then try this out.
driver.driver.find_element(By.XPATH,'//*[#class="pb default"]').click()
or you can search by text Select File
driver.find_element(By.XPATH,'//*[contains(text(),"Select File")]').click()
Well No, you don't click on a <label> element. However, you may require to locate the <label> element for other purposes.
To identify the <label> element you can use either of the following Locator Strategies:
Using css_selector:
element = driver.find_element(By.CSS_SELECTOR, "label.pb.default[for='file']")
Using xpath:
element = driver.find_element(By.XPATH, "//label[#class='pb default' and text()='Select File']")
Update
Element can be within an <iframe> or within a #shadow-root. Otherwise the locator works perfecto:

Python scraping hidden data

I need to scrape text from an object but firstly I have to hover on it. Original code looks like:
<app-tooltip-widget _nghost-tmf-c12="">
<div _ngcontent-tmf-c12="" triggers="" class="">
<img alt="Info icon" class="img-fluid shipments-info-icon" src="info.png">
</div>
</app-tooltip-widget>
When i hover on it:
<app-tooltip-widget _nghost-sqv-c21="">
<div _ngcontent-sqv-c21="" triggers="" class="" aria-describedby="tooltip-21">
<img alt="Info icon" class="img-fluid shipments-info-icon" src="info.png">
</div>
</app-tooltip-widget>
Appear 'aria-describedby="tooltip-21"'
I need scrape information inside
Im trying:
driver = webdriver.Chrome()
driver.get('example.com')
driver.maximize_window()
men_menu = WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.XPATH, '//div[#_ngcontent-sqv-c21=""]')))
ActionChains(driver).move_to_element(men_menu).perform()
data = driver.find_element_by_xpath('//*[#aria-describedby="tooltip-23"]').text
print(data)

Identifying element from nested HTML code under frame using Selenium (confirmed no iframe)

I am learning Selenium using python and was trying to automate form filling in some website.
However, I am unable to identify any element under a frame and it gave me NoSuchElementException error. I have tried using different find_element function e.g. CSS, XPATH (pretty sure the XPATH is correct as i copied it from Firebug) and also tried to include explicit wait using WebDriverWait. However, nothing came through.
The command I have tried before:
driver.find_element_by_id("testFormNumForLastAttempt");
driver.find_element_by_xpath("//input[#type='text' and #name='testFormNumForLastAttempt']");
wait = WebDriverWait(driver, 10)
wait.until(EC.presence_of_element_located((By.ID, "testFormNumForLastAttempt")));
I was trying to switch to another frame
driver.switch_to.frame("main")
raise exception_class(message, screen, stacktrace)
NoSuchFrameException: Message: No frame found
I have extracted the relevant HTML code below and was looking for solution to identify the testFormNumForLastAttempt input parameter.
Thanks in advance. Any help will be much appreciate.
<html>
<frameset rows="0,0,*" frameborder="no" border="0">
<frame name="applet_container" scrolling="no" marginwidth="0" marginheight="0" noresize src="">
<frame name="javascript_container" scrolling="no" marginwidth="0" marginheight="0" noresize src="/repoes/td-es-app517/RETJSContainer_WOC.do?__AUTHENTICATION_REQUEST_PARAMETER_MECHANISM__=applet">
<frame name="main" scrolling="yes" noresize src="/repoes/td-es-app517/Loading.do" marginwidth="0" marginheight="0" frameborder="0">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta http-equiv="Cache-Control" content="no-cache">
<meta http-equiv="Expires" content="0">
<meta http-equiv="Pragma" content="no-cache">
<div id="authByTestForm">
<table width="100%" cellspacing="0" cellpadding="0" border="0">
<tbody>
<tr>
<td>Test Form No. for Last Attempt <span class="star">*</span> </td>
<td>
<input type="text" size="10" maxlength="8" name="testFormNumForLastAttempt" id="testFormNumForLastAttempt" value="" class="uppercase" autocomplete="off">
</td>
</tr>
<tr>
<td valign="top">Date of Birth <span class="star">*</span></td>
<td>
<table class="example_table">
<tbody>
<tr>
<td colspan="7">
<input type="text" size="4" maxlength="4" id="testFormBirthYear" name="testFormBirthYear" onkeyup="moveOnMax(this,'testFormBirthMonth')" value="" autocomplete="off"> Year
<input type="text" size="2" maxlength="2" id="testFormBirthMonth" name="testFormBirthMonth" onkeyup="moveOnMax(this,'testFormBirthDay')" value="" autocomplete="off"> Month
<input type="text" size="2" maxlength="2" id="testFormBirthDay" name="testFormBirthDay" value="" autocomplete="off"> Day
</td>
</tr>
<tr>
<td>Example:</td>
<td class="example_cell">1995</td>
<td>Year</td>
<td class="example_cell">09</td>
<td>Month</td>
<td class="example_cell">08</td>
<td>Day</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</div>
The <input> tag with id as testFormNumForLastAttempt seems to be nested within 3 layers of <frame>.
So to click() within the element you have to:
Ignore (safely) the presence of parent or child <frameset> tags.
Induce WebDriverWait for the first layer of frame_to_be_available_and_switch_to_it().
Induce WebDriverWait for the second layer of _frame_to_be_available_and_switch_to_it().
Induce WebDriverWait for the third layer of frame_to_be_available_and_switch_to_it().
Induce WebDriverWait for the desired element_to_be_clickable().
You can use the following solution:
Code Block:
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.NAME,"applet_container")))
WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR,"frame[name='javascript_container'][src$='__AUTHENTICATION_REQUEST_PARAMETER_MECHANISM__=applet']")))
WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH,"//frame[#name='main' and contains(#src, 'Loading')]")))
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "input#testFormNumForLastAttempt[name='testFormNumForLastAttempt']"))).click()
You can find a relevant discussion in How to locate and click on an element which is nested within multiple frame and frameset through Selenium using Webdriver and C#
Outro
How can I select a html element no matter what frame it is in in selenium?
Ways to deal with #document under iframe

Selenium webdriver is not finding the Inbox element

Bumping this from two months ago since I have not found a solution. I am using Firefox driver to find and then click on a hyperlink named "Inbox" but after exhaustive attempts, Selenium still can't find the element. Any help would be appreciated as I genuinely have not been able to find a reason why Selenium webdriver cannot find the element.
In the below HTML code, I have considered that there might be a frame but none can be found; if someone could confirm that there in fact is no iframe in the below code that would be appreciated! I also already have a time.sleep(40) in my script to allow for enough time for webdriver to find the element. So I am running out of ideas, but was thinking that maybe the #text element (" &nbsp") right before the "inbox" hyperlink element might be causing the issue by hiding the "inbox" element? Any tips on how to proceed would be appreciated; all my attempts at resolution are listed below.
Below is my code up until this element issue comes up (URL has been removed as it is proprietary):
from selenium import webdriver
import time
driver = webdriver.Firefox()
driver.get("[URL REMOVED]")
time.sleep(2)
elem1 = driver.find_element_by_css_selector('#main-content > div > div.col-md-4.radix-layouts-sidebar.sidebar-right.panel-panel.sidebar > div > div.panel-pane.pane-entity-field.pane-it-service-field-related-services.block > div > div > ul > li:nth-child(1) > a')
elem1.click()
#Logging in
time.sleep(40)
#Now in the System, click on Inbox Button
elem2 = driver.find_element_by_??? # Trying to figure out this code to find inbox element
elem2.click()
I have tried the below in trying to find the element :
find_element_by_xpath('//td[#class=’MENUCHOICE’]//a[#href="main.do?action=inbox"]')
find_element_by_xpath('/html/body/table/tbody/tr[6]/td/a')
find_element_by_link_text('Inbox')
find_element_by_partial_link_text('Inb')
find_element_by_css_selector('body > table > tbody > tr:nth-child(6) > td > a')
find_element_by_css_selector("td.MENUCHOICE a[href='main.do?action=inbox']")
All the locators I have tried raise 'selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element'
I cannot provide the link to the page as it's proprietary, but below I have provided the page HTML in case someone can assist (The element of interest is under the second to last MENUCHOICE class: Inbox):
<html>
<!--702.15-->
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta http-equiv="Cache-Control" content="no-cache">
<meta http-equiv="Expires" content="0">
<meta http-equiv="Pragma" content="no-cache">
<title>UDM - Notification System</title>
<style type="text/css">
td.MENU1 {
FONT-FAMILY: Verdana, Arial, Helvetica, sans-serif;
FONT-SIZE: 18pt;
FONT-WEIGHT: medium;
color: navy;
}
td.MENU2 {
FONT-FAMILY: Verdana, Arial, Helvetica, sans-serif;
FONT-SIZE: 15pt;
FONT-WEIGHT: medium;
color: navy;
}
td.MENUCHOICE {
FONT-FAMILY: Verdana, Arial, Helvetica, sans-serif;
FONT-SIZE: 14pt;
FONT-WEIGHT: medium;
color: blue;
}
</style>
</head>
<body bgcolor="#ffffff" background="payadm/images/background.gif">
<table width="750" border="0">
<tbody>
<tr>
<td><img height="55" width="129" src="payadm/images/udm_cw100.gif"></td>
</tr>
<tr>
<td> <img src="payadm/images/footerline.gif"></td>
</tr>
<tr>
<td class="MENU1"> AN Main Menu</td>
</tr>
<tr>
<td> </td>
</tr>
<tr>
<td class="MENUCHOICE"> Notification Functions:</td>
</tr>
<tr>
<td class="MENUCHOICE">
Inbox
</td>
</tr>
<tr>
<td class="MENUCHOICE">
Notification Selection
</td>
</tr>
Thanks for the help.
To click the element with text as Inbox you can use either of the following solutions:
css_selector:
find_element_by_css_selector("td.MENUCHOICE a[href='main.do?action=inbox']")
xpath:
find_element_by_xpath("//td[#class='MENUCHOICE']//a[#href='main.do?action=inbox' and contains(.,'Inbox')]")
This issue was resolved a month ago. It turns out that for this particular web application, Selenium webdriver needed to have a direct link from the get-go; otherwise it would not "recognize" the page it was on. This web app is usually not linked to directly; you usually go through an intermediary page that has the link posted.
I resolved this by directing Selenium to the web application directly instead of going through the intermediary page first and clicking on the web app link. I.e.:
from selenium import webdriver
import time
driver = webdriver.Firefox()
driver.get("[DIRECT LINK INSTEAD OF INTERMEDIARY PAGE LINK]")
Hope this helps anyone with a similar issue in the future.

Python Selenium send_keys not typing text

I am trying to type 8 to cell by using friday.send_keys(8) but it doenst type number, and I dont get any error on my script too.
I can see my click is working, but send_keys is not working. I have tried multiple ways, and I have look all other SO question on this nothing really helped.
I downgrade my Firefox to 28
Selenium Version 2.53.6
cursor looks like
friday = driver.find_element_by_xpath("//td[#class=' x-grid-cell x-grid-cell-gridcolumn-1111 ']")
time.sleep(5)
friday.click()
friday.send_keys(8)
HTML element
<td class="x-grid-cell x-grid-cell-gridcolumn-1111">
<div class="x-grid-cell-inner" style="text-align: center; ;"></div>
</td>
IF you click on cell and do inspect html element adds <input>
<td id="textfield-1134-bodyEl" class="x-form-item-body" role="presentation" colspan="3" style="width: 100%;">
<input id="textfield-1134-inputEl" class="x-form-field x-form-text" type="text" autocomplete="off" name="03/03/2017" aria-invalid="false" data-errorqtip="" style="-moz-user-select: text; width: 100%;"></input>
Problem solver by:
friday_time = driver.find_element_by_name("03/03/2017")
friday_time.send_keys(8)
friday_time.send_keys(Keys.ENTER)
Thank you
#WillemVanOnsem

Categories

Resources