Selenium Python - Upload image when element seems to be hidden - javascript

So basically I have problem uploading some photo using Selenium Python
input element seems to be hidden in the page so the .sendkeys method at still I run into some errors.
this is html code of the input element
<div data-react-class="ImageUploadForm" data-react-props="{}" data-react-cache-id="ImageUploadForm-0">
<input class="hidden" type="file" accept="image/jpeg, image/jpg, image/png, image/gif">
<button class="btn btn-lemonfrog text-lg" type="button">Upload photo</button>
</div>
base_path = Path(file).parent
filepath = (basepath / "../core/attachments/clientstackphoto.jpeg").resolve()
hiddenuploaderinput.sendkeys(filepath)
right now after running above code I'm getting type error :
value = (PosixPath('........./core/attachments/clientstackphoto.jpeg'),)
def keys_to_typing(value):
"""Processes the values that will be typed in the element."""
typing = []
for val in value:
if isinstance(val, Keys):
typing.append(val)
elif isinstance(val, int):
val = str(val)
for i in range(len(val)):
typing.append(val[i])
else:
for i in range(len(val)):
E TypeError: object of type 'PosixPath' has no len()
../../venv/lib/python3.7/site-packages/selenium/webdriver/common/utils.py:150: TypeError
I expect to upload photo successfully, maybe some js injection will help ?

Based on your error message, I'm not entirely convinced the error message is caused by the hidden file input. If it were, I would expect an ElementNotVisibleException.
However, I do see that the input is hidden, so we should run some JS to reveal the input and perhaps we can rule that out as a potential issue.
Code to show image input
fileInput = driver.find_element_by_xpath("//input[#type='file']")
# display file input so we can send keys
driver.execute_script("arguments[0].style.display = 'block';", fileInput)
Alternatively, you may need to execute script on the class attribute instead:
driver.execute_script("arguments[0].setAttribute('class', 'visible')", fileInput)
Once you execute JS to make the file input visible, you can just send_keys to it like any other input:
fileInput.send_keys("PATH/TO/FILE/HERE")

Related

How to prevent html form refresh on submit?

Hello after searching and trying a lot , i am not able to find the issue so that I am seeking your help to solve my issue.
Here I have a form while clicking on submit button it should call the javascript function and should not redirect or refresh the page .
Here I want to send mail using SMTPJS with attachments by filling the form and choosing the image once the form submitted it should call the sendEmail() function and mail should be send, but when i click on the submit button it's refreshing the page and it's not working accordingly.
<form onsubmit="sendEmail(); reset(); return false">
<div class="col-md-12">
<div class="form-floating">
<input type="file" class="form-control" id="fileupload" required>
<label for="phone">Upload file</label>
</div>
</div>
<div class="col-12">
<button class="btn btn-primary w-100 py-3" type="submit" style="background-color: #0e2e50;">Upload</button>
</div>
</div>
</form>
<script>
function sendEmail() {
var file = event.srcElement.files[0];
var reader = new FileReader();
reader.readAsBinaryString(file);
reader.onload = function () {
var dataUri = "data:" + file.type + ";base64," + btoa(reader.result);
Email.send({
Host: "smtp.elasticemail.com",
SecureToken :"************"
To: 'mail#mail.com',
From: "mail#mail.com",
Subject: "Form Enquiry",
Body : "Sending file:" + file.name,
Attachments : [
{
name : file.name,
data : dataUri
}]
}).then(
message => alert(message)
);
};
}
</script>
I think the issue is in this line 'var file = event.srcElement.files[0];' because from this line it's refreshing the page and a Question mark (?) is coming in the URL. ex.page.html?
One more thing if i am calling the sendEmail() function in the onchange event of the input type file then it's working fine, why so?
You have two problems.
Typo
The first is a typo and is highlighted by the browser telling you:
Uncaught SyntaxError: missing } after property list note: { opened at line 24, column 19
This exception is preventing the function from being created, so the onsubmit function errors when it calls it, and you never reach the return false that prevents the form submission.
Read the error messages in the console in the browser developer tools.
You are missing a comma between SecureToken :"************" and To: 'mail#mail.com'.
Forms don't have files
You said:
var file = event.srcElement.files[0];
Which gets the element that triggered the event (since it is a submit event, that is the <form>) and you try to read the files property from it.
The browser tells you this:
Uncaught TypeError: event.srcElement.files is undefined
Read the error messages in the console in the browser developer tools.
The files property can be found on <input type="file">, not on the <form>.
You need to find the correct element:
var file = event.srcElement.querySelector('[type="file"]').files[0];
Asides
To generally make life easier and avoid these sorts of issues:
Use a linter, like ESLint, and an editor that can use it as a plug in
Use a code formatter to indent code and help locate syntax errors
Don't use intrinsic event attributes (like onsubmit); do use addEventListener
Pay attention to what your debugging tools are telling you
Just change it a little bit:
<form onSubmit="sendEmail(event)">
...
</form>
function sendEmail(event) {
event.preventDefault();
...
}

How to change a HTML-element to the selection of a File-Dialog?

I am currently working on a python program that uses a html/css interface which is connected through eel. It requires the user to load a file to analyze. In order to show the user on the User interface which file was selected, I want to show the name of the file (or the path) after the selection process is done.
Since I am new to this, I found a simple filedialog on the internet (probably somewhere here on Stackoverflow) that uses JQuery to select the path to a file. The selection works fine and my program can work with that information if the file that is being selected is located in the same folder as the html file, as this circumvents fakepath errors and I do not know a way around it.
I want to display the selected path underneath the button once it has been selected. However, in the current configuration it displays [object object] right after clicking the "Browserino" button and not the selected path or (ideally) the selected filename.
The HTML document contains:
<div class="col">
<button id="button" class="btn btn-primary" onclick="clicked();">Browserino</button>
<input id="file-input" type="file" name="name" style="display: none;" />
<small id="pathway" class="form-text text-muted">invisible</small>
</div>
And the main.js has this function to work with:
function clicked(){
var path = String($('#file-input').trigger('click'));
document.getElementById('pathway').innerHTML = path;
document.getElementById('pathway').style.visibility = 'visible';
}
I have also tried the follwing in the main.js, but it does not do the trick for me:
function clicked(){
String($('#file-input').trigger('click'));
var file_input = document.getElementById('file-input').value;
var filepath = file_input.replace(/^.*[\\\/]/, '');
document.getElementById('pathway').innerHTML = filepath;
}
Thanks for all the comments before, I hope this edit helps clarify the problem. Any help is appreciated. Thx.

Change programmatically IID_IHTMLInputFileElement value

I tried for several days to programmatically put a file path into a input type file element into a CHtmlView control (IE). I have tried this:
IHTMLInputFileElement* pInputElem = NULL;
hr = pElemDispatch->QueryInterface(IID_IHTMLInputFileElement, (void**)&pInputElem);
CString sFile(_T("C:\\Flaviu\\SomeFile.txt"));
BSTR bstrFilesAttribute = sFile.AllocSysString();
hr = pInputElem->put_value(bstrFilesAttribute); // hr is S_OK though
SysFreeString(bstrFilesAttribute);
but didn't work, I mean there is no SomeFile.txt chosen on input file.
I have read on several sites that I cannot edit or set value on an input type file element for security reason.
Somewhere, someone, suggested a simple solution: to make a copy of the original web page, and edit html source code and replace input type file element to an input type text. Which I have done. I only have to solve "action" attribute on form:
Original html source code:
<form name="uf" method="POST" action="/WS6ERT/SomeFile.do" enctype="multipart/form-data">
<div style="background-color: #c6c6c6; padding: 5px">
<span>Choose file:</span> <span> <input type="file" name="linkdoc" size="75" value=""></span><span><input type="submit" value="Send"></span>
</div>
</form>
and I made a copy, and I replaced input type file, with input type text:
<form name="uf" method="POST"
action="https://originalsite.com/WS6ERT/SomeFile.do" enctype="multipart/form-data">
<div style="background-color: #c6c6c6; padding: 5px">
<span>Choose file::</span> <span> <input type="text" name="linkdoc">
</span><span><input type="submit" value="Send"></span>
</form>
The important tags attribute: "action="
Of course that is not correct what I have written in my html source, because my path is pointing on the original file, which I didn't edit...
Is there a way to solve this issue? To put programmatically a file path into an input type file on a CHtmlView view? Or how to overcome this problem?
Last Edit: Can I setup the file with javascript ? I saw here: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file#attr-files that is possible to setup a file in files attribute. But I don't know how to do that ...
If you have a handle to CHtmlView* then use CHtmlView::Navigate2 or CHtmlView::Navigate
This should do the job unless html control is busy with a previous request, for example you already made a Navigate request and the html control is not finished processing that request. In the case, you can override CHtmlView::OnNavigateComplete2, which lets you know the html control is finished with the previous navigation request, and it can receive a new request. Alternatively you could use a wait function to wait for the control to finish using the for loop shown below.
CString filename = _T("C:\\Test\\test.html");
CStringW content = LR"(<html><body> content </body></html>)";
//optional: in case the control is busy with previous request
for(int i = 0; i < 100; i++)
{
MSG msg;
while(::PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))
if(!AfxGetThread()->PumpMessage())
break;
CFile test;
if(test.Open(filename, CFile::modeNoTruncate | CFile::modeWrite))
break;
}
CFile fout;
if(fout.Open(filename, CFile::modeCreate | CFile::modeWrite))
{
content = LR"(<html><body> content UPDATE </body></html>)";
CStringA utf8 = CW2A(content, CP_UTF8);
fout.Write(utf8, utf8.GetLength());
fout.Close();
htmlview->Navigate(filename, 0, NULL);
}

Html - Javascript: text

I have the following text inside a form on a jsp page:
<td id="seltb71b" style="display: none">
<input type="text" id="tb73Parametro" name="tb73Parametro" value="${varTb73Parametro}" />
</td>
Now, this text doesen't always appear on the page, it appears only when a select is selected. On java side, i have the class Form with all validators and one of them is raised when the text is empty.
#UseValidators({
#UseValidator(value = StringLength.class, args = { "1", "50" }, error = "tb71Validator")
#UseValidator(value = NotNull.class, error = "tb71Validator")
})
public String tb71;
The question is: how can i call the form error validator using javascript? (client side).
I can't add the error validator on java (server side) because if the text doesen't appear the error is however called and this is no good.
The validator must rise only when the text appears AND is empty.

Retrieve variable name from an HTML site

I am trying to retrieve simple javascript variable (which is written to a File Systems Object) from a website which is served by an apache host on my ubuntu laptop.
So I have the function that writes the variable set up as follows:
<script type ="text/javascript">
function WriteToFile(passForm) {
set fso = CreateObject("Scripting.FileSystemObject");
set s = fso.CreateTextFile("/home/lex/Downloads/goal.txt", true);
s.writeline(document.passForm);
s.Close();
}
</script>
and the section that takes the user input from the html website is
<div id="bot-right">
<form onsubmit="WriteToFile(this['goal'].value)">
<a align = "left"> <b><Strong>Enter a Goal name</Strong></b></a><br>
<input type="text" name="goal"> <br>
<input type="submit" value="Send Zeus">
<br>
</form>
</div>
For some reason, when I type in variable names to the form on the website, the file goal.txt gets created in the directory, /home/lex/Downloads/, but nothing gets written to it.
I also noticed that when I delete the goal.txt file and rewrite the variable from the html website, the file doesn't always get created.
I am not a JavaScript person and I am at a loss as to what I may need to fix this.
My intention is to get the variable written to the text file and have a processing c++ file process the variable.
Would someone be kind enough to lend an insight?
Thanks!
one way to do it is just calling the function without parameters and just getting the input value like this:
adding and id or a class to your input to get that specific value:
document.getElementById('goal').value
document.getElementByClass('goal').value
Or getting the value by name:
document.querySelector('[name="goal"]').value;
EDIT1
You could add a console.log to check if the value is beign passed correctly like this:
var inputValue = document.querySelector('[name="goal"]').value;
console.log(inputValue);
And if the value is being passed then the problem is your writeline or in the creation of the document
EDIT2
I just tested it and retrieving the value works just fine, so the problem must be in your document writing method, please check this documentation it can help you and i think is a better solution:
http://www.html5rocks.com/en/tutorials/file/filesystem/

Categories