Accessing a file dialog inside an iframe - selenium

I have an inline jsp page which has the code for the html type: file. The below displayed IFRAME tag is in the main jsp. I want to pass on the file name and submit this file dialog using the web driver. Basically want to do something like:
WebElement elem = driver.findElement(By.id("attachmentfile"));
elem.sendKeys("C:\\Users\\Public\\Pictures\\Sample Pictures\\Koala.jpg");
However, am not able to get a hold of the attachmentfile id. Any help would be appreciated. Thanks.
Main Jsp:
<IFRAME id=fileupload src="fileupload.jsp?type=uploadbutton"
frameBorder=0></IFRAME></TD></TR></FORM>
The fileupload.jsp is as below:
<html> <body>
<form name="frm_fileUpload" ENCTYPE="multipart/form-data"><%
<tr>
<td>
<input type="file" name="attachmentfile"
id="attachmentfile" onChange="uploadFile ();" />
<input type="button" name="uploadbutton" id="uploadbutton"
value="Upload" class="button" />
</td>
</tr>
</table>
</form>
</body>
</html>

Related

Why can I click an input with type=radio of a h:selectOneRadio, but not one of a p:selectOneRadio with Graphene/Selenium?

A h:selectOneRadio results in <input type="radio"> in a table and p:selectOneRadio in <input type="radio"> in a table with some divs around the input. The id for both is [form id]:[selectOneRadio id]:[option number] which I can use successfully for the plain JSF in a Graphene functional test when accessing it with #FindBy(id="[...]") whereas the PrimeFaces variant fails due to org.openqa.selenium.ElementNotInteractableException. Investigating the generated HTML I don't see the difference
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<link type="text/css" rel="stylesheet" href="/34696ceb-eeaa-4b35-88dd-f3c8fc5901bf/javax.faces.resource/theme.css.xhtml?ln=primefaces-aristo">
<link type="text/css" rel="stylesheet" href="/34696ceb-eeaa-4b35-88dd-f3c8fc5901bf/javax.faces.resource/primefaces.css.xhtml;jsessionid=48ca919d0b7e89661f92149ac321?ln=primefaces&v=5.0">
<script type="text/javascript" src="/34696ceb-eeaa-4b35-88dd-f3c8fc5901bf/javax.faces.resource/jquery/jquery.js.xhtml;jsessionid=48ca919d0b7e89661f92149ac321?ln=primefaces&v=5.0"></script>
<script type="text/javascript" src="/34696ceb-eeaa-4b35-88dd-f3c8fc5901bf/javax.faces.resource/primefaces.js.xhtml;jsessionid=48ca919d0b7e89661f92149ac321?ln=primefaces&v=5.0"></script>
<title>Facelet Title</title>
</head>
<body>
<form id="mainForm" name="mainForm" method="post" action="/34696ceb-eeaa-4b35-88dd-f3c8fc5901bf/index.xhtml;jsessionid=48ca919d0b7e89661f92149ac321" enctype="application/x-www-form-urlencoded">
<input name="mainForm" value="mainForm" type="hidden">
<table id="mainForm:mainSelectOneRadio">
<tbody>
<tr>
<td>
<input name="mainForm:mainSelectOneRadio" id="mainForm:mainSelectOneRadio:0" value="a" type="radio">
<label for="mainForm:mainSelectOneRadio:0"> a</label>
</td>
<td>
<input name="mainForm:mainSelectOneRadio" id="mainForm:mainSelectOneRadio:1" value="b" type="radio">
<label for="mainForm:mainSelectOneRadio:1"> b</label>
</td>
<td>
<input name="mainForm:mainSelectOneRadio" id="mainForm:mainSelectOneRadio:2" value="c" type="radio">
<label for="mainForm:mainSelectOneRadio:2"> c</label>
</td>
</tr>
</tbody>
</table>
<table id="mainForm:mainSelectOneRadioPrime" class="ui-selectoneradio ui-widget">
<tbody>
<tr>
<td>
<div class="ui-radiobutton ui-widget">
<div class="ui-helper-hidden-accessible">
<input id="mainForm:mainSelectOneRadioPrime:0" name="mainForm:mainSelectOneRadioPrime" value="aPrime" type="radio">
</div>
<div class="ui-radiobutton-box ui-widget ui-corner-all ui-state-default"><span class="ui-radiobutton-icon ui-icon ui-icon-blank"></span>
</div>
</div>
</td>
<td>
<label for="mainForm:mainSelectOneRadioPrime:0">aPrime</label>
</td>
<td>
<div class="ui-radiobutton ui-widget">
<div class="ui-helper-hidden-accessible">
<input id="mainForm:mainSelectOneRadioPrime:1" name="mainForm:mainSelectOneRadioPrime" value="bPrime" type="radio">
</div>
<div class="ui-radiobutton-box ui-widget ui-corner-all ui-state-default"><span class="ui-radiobutton-icon ui-icon ui-icon-blank"></span>
</div>
</div>
</td>
<td>
<label for="mainForm:mainSelectOneRadioPrime:1">bPrime</label>
</td>
<td>
<div class="ui-radiobutton ui-widget">
<div class="ui-helper-hidden-accessible">
<input id="mainForm:mainSelectOneRadioPrime:2" name="mainForm:mainSelectOneRadioPrime" value="cPrime" type="radio">
</div>
<div class="ui-radiobutton-box ui-widget ui-corner-all ui-state-default"><span class="ui-radiobutton-icon ui-icon ui-icon-blank"></span>
</div>
</div>
</td>
<td>
<label for="mainForm:mainSelectOneRadioPrime:2">cPrime</label>
</td>
</tr>
</tbody>
</table>
<input name="javax.faces.ViewState" id="j_id1:javax.faces.ViewState:0" value="-485558793831512050:990657069126697889" autocomplete="off" type="hidden">
</form>
</body>
</html>
nor do I if I deploy the application on Payara 4.1.2 or any other reason for the ElementNotInteractableException.
The access is done with
#RunWith(Arquillian.class)
public class MyManagedBeanTest {
private static final String WEBAPP_SRC = "src/main/webapp";
private final static Logger LOGGER = LoggerFactory.getLogger(MyManagedBeanTest.class);
#Deployment(testable = false)
public static Archive<?> createDeployment0() throws TransformerException, XPathExpressionException, ParserConfigurationException, SAXException, IOException {
WebArchive retValue = ShrinkWrap.create(WebArchive.class)
.add(EmptyAsset.INSTANCE, "beans.xml")
.addClasses(MyManagedBean.class)
.addAsWebInfResource(
new StringAsset("<faces-config version=\"2.0\"/>"),
"faces-config.xml");
Maven.configureResolver().workOffline().resolve("richtercloud:graphene-click-input-radio:war:1.0-SNAPSHOT").withoutTransitivity().asList(JavaArchive.class).forEach(dependency -> retValue.addAsLibrary(dependency));
//add all webapp resources
retValue.merge(ShrinkWrap.create(GenericArchive.class)
.as(ExplodedImporter.class)
.importDirectory(WEBAPP_SRC)
.as(GenericArchive.class), "/", Filters.include(".*\\.(xhtml|css|js|png)$"));
ByteArrayOutputStream archiveContentOutputStream = new ByteArrayOutputStream();
retValue.writeTo(archiveContentOutputStream, Formatters.VERBOSE);
LOGGER.info(archiveContentOutputStream.toString());
return retValue;
}
#Drone
private WebDriver browser;
#ArquillianResource
private URL deploymentUrl;
#FindBy(id = "mainForm:mainSelectOneRadio:0")
private WebElement mainSelectOneRadioOption0;
#FindBy(id = "mainForm:mainSelectOneRadioPrime:0")
private WebElement mainSelectOneRadioPrimeOption0;
#Test
public void testAll() {
browser.get(deploymentUrl.toExternalForm()+"index.xhtml");
LOGGER.debug(browser.getPageSource());
mainSelectOneRadioOption0.click();
mainSelectOneRadioPrimeOption0.click();
}
}
I'm searching for a solution which triggers JSF action methods and AJAX listeners!
I'd be interested in a generic approach as well, e.g. p:selectOneButton produces
<div id="mainForm:mainSelectOneButtonPrime" class="ui-selectonebutton ui-buttonset ui-widget ui-corner-all">
<div class="ui-button ui-widget ui-state-default ui-button-text-only ui-corner-left">
<input id="mainForm:mainSelectOneButtonPrime:0" name="mainForm:mainSelectOneButtonPrime" value="aPrime" class="ui-helper-hidden" type="radio">
<span class="ui-button-text ui-c">aPrime</span>
</div>
<div class="ui-button ui-widget ui-state-default ui-button-text-only">
<input id="mainForm:mainSelectOneButtonPrime:1" name="mainForm:mainSelectOneButtonPrime" value="bPrime" class="ui-helper-hidden" type="radio">
<span class="ui-button-text ui-c">bPrime</span>
</div>
<div class="ui-button ui-widget ui-state-default ui-button-text-only ui-corner-right">
<input id="mainForm:mainSelectOneButtonPrime:2" name="mainForm:mainSelectOneButtonPrime" value="cPrime" class="ui-helper-hidden" type="radio">
<span class="ui-button-text ui-c">cPrime</span>
</div>
</div>
<input name="javax.faces.ViewState" id="j_id1:javax.faces.ViewState:0" value="-5130093024933213812:2291815208147638618" autocomplete="off" type="hidden">
which doesn't seem to have anything in common with the HTML generated for p:selectOneRadio at first sight. Maybe there's a trick.
I'm using PrimeFaces 6.1.
ui-helper-hidden-accessible is a JQuery layout helper to hide items visually. The radio button you see is actually the parent element, <div class="ui-radiobutton ui-widget">.
The problem can be resolved by clicking on the radio button label. The 'for` attribute put the focus on the input label associated with it
#FindBy(css = "[for='mainForm:mainSelectOneRadioPrime:0']")
private WebElement mainSelectOneRadioPrimeOption0;
#Guy has the right answer.
The issue here is that PrimeFaces is applying its own styling on top of the HTML which is covering the element you are trying to click.
Selenium checks that the targeted element mainForm:mainSelectOneRadio:0 receives the events when the element on top is clicked. But in this case the overlay is done with a sibling container which is not an descendant of targeted element. Thus Selenium assumes that the element will not receive the events and raises an ElementNotInteractableException (see event bubbling and propagation).
You can clearly see the issue by visiting oneRadio.xhtml and by inspecting the radio button with a right click. You'll see that the selected DOM element and the <input> are located in two different branches of the DOM tree.
To overcome this issue, either click the label since it has no overlay (see solution from #Guy). The label has the for attribute which mean that all the events are forwarded to the element assigned to for which is the targeted <input>.
You could also directly click the overlay. Though, you'll have to use an XPath to express the relationship.
Parent of parent of the targeted <input> :
#FindBy(xpath = "id('mainForm:mainSelectOneRadioPrime:2')/../..")
private WebElement mainSelectOneRadioPrimeOption0;
Or first <td> having the targeted <input> :
#FindBy(xpath = "//td[.//input[#id='mainForm:mainSelectOneRadioPrime:2']]")
private WebElement mainSelectOneRadioPrimeOption0;

Jquery dynamically added inputs to form have not POST data PHP

I'm adding <input> fields in form using jquery html() on click event.
$('#container').html('<input type="text" name="ce" value="some" >');
after submitting php POST i'm unable to see index ce with print_r($_POST);
is there any special method to add elements to dom for this ? please advise.
Solved ! Thanks for answering. in my scenario even with append it didn't work. now it's done with my previous code using html(). Problem was wrapping the <form>. my table is large i'm only pointing out the problem. my structure was suppose to like:
<table>
<tr>
<form id="myform">
<td><input type="text" name="name" ></td>
<td>
<div id="container">
<!-- dynamically generated inside this div against it's id (which didn't work) -->
<input type="text" name="ce" >
</div>
</td>
</form>
</tr>
</table>
i simply Put the entire table into the 'form' tags
<form id="myform">
<table>
<tr>
<td><input type="text" name="name" ></td>
<td>
<div id="container">
<input type="text" name="ce" > <!-- dynamically generated inside div (works!) -->
</div>
</td>
</tr>
</table>
</form>
it worked perfectly with both append() and html(). hope will be helpful for someone.
When you do $('#container').html you are not adding a new input, you are replacing all your content with this new input..
try $('#container').append tag
Look at this example -> https://jsfiddle.net/660a3t1g/
$('#myInputs').append('<input type="text" placeholder="LastName: " name="some" >');

Display result of File Upload using Coldfusion.Navigation?

I want to use a single home page where I will display an upload form (which is in another file). After uploading (action file result) I want to show the result of upload on the same page.
These are my three files:
index.cfm
<html>
<head>
<title>HomePage</title>
<cfajaximport tags="CFFORM">
</head>
<body>
<cfdiv id="Main" style="width:1000px; height:600px" >
<cfdiv id="Options" style=" width:100%;height:20%" >
Welcome Admin, Update Logout
</cfdiv>
<cfdiv id="Content" style=" width:100%;height:80%">
<h2>Here Goes Form and FileUploading</h2>
</cfdiv>
</cfdiv>
</body>
</html>
FileUpload.cfm
<html>
<head>
<title>Upload A File</title>
</head>
<body >
<cflayout type="vbox" name="layout1">
<cflayoutarea>
<cfform enctype="multipart/form-data" action="FileReceiver.cfm" >
File To Upload:
<cfinput type="file" name="Filename" size="50" >
<br/>
<cfinput type="submit" name="UploadFile" value="UPLOAD THIS FILE">
<br/>
</cfform>
</cflayoutarea>
<cflayoutarea>
<table border="1" >
<tr>
<th >
Directory Information
</th>
</tr>
<tr>
<td>
<cfoutput >
CurrectDirectory Path: #getdirectoryFromPath(expandPath("index.cfm"))#
</cfoutput>
</td>
</tr>
</table>
</cflayoutarea>
</cflayout>
</body>
</html>
FileReceiver.cfm
<cfif isdefined('UploadFile') >
<cfoutput >
<cffile nameconflict="makeunique"
action="upload"
filefield="Form.Filename"
destination="#getdirectoryFromPath(expandPath("index.cfm"))#" >
<!--- or destination="c:\Upload\"--->
File upload was successful!
</cfoutput>
</cfif>
When I click on "update link", the index page shows the FileUpload.cfm page in one of its containers. But when uploading file I always get an error message:
Error retrieving markup for element cf_layoutarea736558924094373 :
Invalid content type: application/x-www-form-urlencoded;
charset=UTF-8. [Enable debugging by adding 'cfdebug' to your URL
parameters to see more information]
Kindly help me do it the right way, as I am unable to figure out the problem.
I guess you are not getting your Form scope values actually.
To upload a file, you have used multipart/form-data which are correct and also default value for method attribute in cfform is POST which also looks ok.
Probably issue is because of CFFileNonMultipartException.
Dump FORM scope before Upload code to check you are getting all form values or not on filereciever.cfm.
You can also try without cfform
<form action="FileReceiver.cfm" method="post" enctype="multipart/form-data">
<input type="file" name="Filename">
<input type="submit" name="UploadFile" value="UPLOAD THIS FILE">
</form>
In what is likely a mistyped cffile tag, you have this:
filefield="Form.Filename"
The documentation for cffile, suggests that you should just just have the name of the form field, without the qualification.
Yes Dharmesh, you can do bit trick here. Get rid of fileReciever.cfm page. Add this code in index.cfm
<cfif structKeyExists(FORM,"filename")>
<cffile action="upload" filefield="Form.Filename" destination="#getdirectoryFromPath(expandPath("index.cfm"))#" result = "fileUploaded">
<cfif isDefined("fileUploaded") AND fileUploaded.FILEWASSAVED EQ "yes">
Success
</cfif>
</cfif>
and submit your form to index.cfm not on fileReceiver.cfm

Need unique field to identify using Selenium WebDriver

I need to find the the unique field to identify the search box and enter text in it.
<style type="text/css">
</head>
<body style="min-height: 81px;">
<div class="shared-page" data-cid="view221" data-view="views/shared/Page" data-render-time="0.02">
<a class="navSkip" tabindex="1" href="#navSkip">Screen reader users, click here to skip the navigation bar</a>
<header role="banner">
<a id="navSkip"></a>
<div class="main-section-body" role="main">
<div class="timeline" data-cid="view4947" data-view="views/timeline/Master" data-render-time="0.107">
<div class="section-padded section-header">
<div class="timeline-title" data-cid="view5085" data-view="views/timeline/Title" data-render-time="0.001">
<div class="search-bar-wrapper shared-searchbar" data-cid="view4948" data-view="views/shared/searchbar/Master" data-render-time="0.104">
<form class="search-form" action="" method="get">
<table class="search-bar search-bar-primary">
<tbody>
<tr>
<td class="search-input" width="100%">
<div id="search" class="shared-searchbar-input" data-cid="view4949" data-view="views/shared/searchbar/Input" data-render-time="0.002">
<div class="search-field-background"> </div>
<div class="search-field-wrapper">
<label class="placeholder-text" for="397271.5897375417" style="display: block;">enter search here...</label>
<textarea id="397271.5897375417" class="search-field" autocapitalize="off" autocorrect="off" spellcheck="false" name="q" rows="1"></textarea>
textarea is the field related to the search box. I tried using class, name but it says unable to locate element, the numeric id too is dynamic. Please let me know what to use in this case.
It should be possible to find this element by class name
in ruby:
driver.find_element(:class, "search-field")
or in java:
driver.findElement(By.className("search-field"));
Following xpath should work:
//div[#id='search']//textarea[#class='search-field']
If the <textarea> is only one, you can search with
driver.findElement(By.tagName("textarea"));
Use xpath,
driver.findElement(By.xpath("//textarea[#class='search-field']"));
Or
driver.findElement(By.name("q"));

Assign a File Path to WBC Web Page Input

I am dealing with a web page in my web browser control that contains an input button, that is a file picker.
<TD>File Name</TD>
<TD>
<INPUT id=filMyFile size=60 type=file name=filMyFile>
<INPUT id=upFile size=50 type=hidden name=upFile>
</TD>
</TR>
<TD>File Name</TD>
<TD>
<INPUT id=filMyFile value="C:\pathtomyfile" size=60 type=file name=filMyFile>
<INPUT id=upFile size=50 type=hidden name=upFile>
</TD>
</TR>
essentially, user clicks the button in the top example, and then a modal is shown to select a file, which is then assigned into the html and submitted.
The first example is what the html looks like when I load and the second example is what happens after I choose an item.
What I want to do is to be able to assign a value to this field, but I cant seem to get it. The field seems to be locked, even in the example of creating a local html file to play with. I tried .getelementbyid("filmyfile").setattribute to assign value, as well as, using .innerhtml and .outerhtml, and none were successful.
How do I assign an item path to this field programatically? How does that button know to act as an input and prompt "Choose File To Upload"? Is this some default deal in html pertaining to buttons?
You can't for security reasons. Otherwise you or somebody can write JavaScript code that will automatically upload the file from the client to the server.
For instance the following code would grab secret.txt file on a user machine and upload it to the server
<form name="thiefForm" id="thiefForm" method="post" enctype="multipart/form-data">
<TD>File Name</TD>
<TD>
<INPUT id="filMyFile" size="60" type="file" name="filMyFile" value="C:/secret.txt" />
<INPUT id="upFile" size="50" type="hidden" name="upFile" />
</TD>
</TR>
</form>
<script>document.thiefForm.submit();</script>