How to locate a hidden element on a webpage - python-2.7

I am trying to pass some content in the textbox using the following:
driver.find_element_by_xpath('path').send_keys(value)
Apparently nothing is getting passes.
Similar issue with clicking button:
driver.find_element_by_xpath('path').click()
This is also not working, in the code i could see
display:none:
<li style="display:none">
</li>
</ul></div>
<div class="row form-group">
<div class="col-sm-12 form-group">
<label for="Username">Username</label>
<input autocomplete="off" class="form-control" data-val="true" data-val-
required="User name is Required" id="Username" name="Username" type="text" value="">

As per the HTML you have shared and #Sighil pointed out the style attribute display: none is part of the previous <li> tag which must not affect the Username field. To pass some text to the Username field you can use the following line of code :
driver.find_element_by_xpath("//input[#class='form-control' and #id='Username']").send_keys("Dimple Mathew")
It may be possible you have to induce a waiter for the Username field to be interactable and in that case you have to induce WebDriverWait as follows :
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//input[#class='form-control' and #id='Username']"))).send_keys("Dimple Mathew")

Use explicit wait statement before you use sendkeys or click. As per my understanding element is not visible while click or sendkeys.
For your reference visit Explicit and Implicit Wait Docs

I was having a similar issue not to long ago, try this:
js= "document.getElementById('Username').value = '" + str(YOURVALUE) + "';"
driver.execute_script(js)
It worked for me, hope this helps.

Related

How can I get custom form field value from within Django Admin's response_change?

I've added a custom functionality to a model by overriding change_form.html. Basically, I'm letting users change the objects of a model if these changes were approved by the admin. I added two buttons, named accept-suggestion and decline-suggestion and I intend to handle the custom functionality through response_change method:
def response_change(self, request, obj):
if "decline-suggestion" in request.POST:
# do stuff...
if "accept-suggestion" in request.POST:
# do stuff...
Both buttons will send an e-mail to the user saying if the suggestion was declined or approaved. So far so good. The problem is that I want to add the possibility to the admin write a brief justification explaining why the suggestion was declined. So I changed change_form.html again.
<div class="submit-row">
<div class="float-left">
<a class="decline-button-outlined accordion" type="button" href="#">DECLINE SUGGESTION</a>
</div>
<div class="float-right">
<input class="accept-button" type="submit" name="accept-suggestion" value="ACEITAR SUGESTÃO">
</div>
</div>
<div class="additional-infos">
<fieldset class="module aligned">
<div class="form-row">
<label for="decline-reasons">Reasons for rejection:</label>
<textarea
placeholder="If you find necessary, provide information on the reasons that led to the rejection of the suggestion"
id="decline-reasons" class="vLargeTextField" rows="5"></textarea>
</div>
<div class="submit-row">
<div class="float-right">
<input class="decline-button" type="submit" name="decline-suggestion" value="DECLINE">
</div>
</div>
</fieldset>
</div>
Is this the best approach? If so, how can I get the value of the <textarea> above from within response_change? If not, what would you suggest?
Thank you very much!
If you add a name to your <textarea> you will be able to retrieve the contents on the server side. Without a name, the data is not being sent to the server (Django).
So something like this:
<textarea
placeholder="If you find necessary, provide information on the reasons that led to the rejection of the suggestion"
id="decline-reasons" name="decline-reasons" class="vLargeTextField" rows="5"></textarea>
Should allow you to retrieve the text on the Django side with request.POST["decline-reasons"].

g:render tag renders body() as plain text

I'm trying to render the template in GSP page
template:
<div class="container">
${body()}
</div>
template call:
<g:render template="/shared/wrapperTemplate">
<g:textField name="${property}" value="${value}" id="${property}id" class="form-control"/>
</g:render>
The body() is evaluated correctly and renders
<input type="text" name="name" value="" id="nameid" class="form-control" />
but when passing it to the template, it is surrounded by the quotes and instead of displaying input field, it prints the html input as string to the html page
I also tried with write TagLib
def fieldTemplate = { attrs, body ->
out << render(template: "/shared/wrapperTemplate", model: [content: body()])
}
But the result was the same (of course I had to change the tag call)
The idea was to reuse the formatting part of the template <div> for all _wrapper.gsp templates in Fields plugin, but not copy paste it. The case above is simplified, but I use Twitter Bootstrap and there is a bunch of lines that I don't want to copy.
_fields/default/_wrapper.gsp:
<div class="form-group ${hasErrors(bean:bean,field:property,'has-error')}">
<label for="${property}id" class="col-sm-2 control-label">${label}</label>
<div class="col-sm-10">
<g:textField name="${property}" value="${value}" id="${property}id" class="form-control" />
</div>
</div>
_fields/date/_wrapper.gsp:
<div class="form-group ${hasErrors(bean:bean,field:property,'has-error')}">
<label for="${property}id" class="col-sm-2 control-label">${label}</label>
<div class="col-sm-10">
<g:datePicker name="${property}" value="${value}" precision="day" id="${property}id" class="form-control" />
</div>
</div>
I am not able to understand the following lines of your post
but when passing it to the template, it is surrounded by the quotes
and instead of displaying input field, it prints the html input as
string to the html page
What is it in this case, please share the exact code which is not working.
The first example you shared is working for you, in the second example you passed content as parameter. When you are passing the parament then you need to change your code from
${body()}
to
${raw(content)}
I am still not sure what is the exact code which not working, just a wild guess.

Adding extra HTML tags and attributes to Django crispy-forms fields

I'm using django-crispy-forms with Bootstrap and I'm wanting to add some extra HTML inside the HTML rendered for the a single field.
For example if my form contains,
recipients = forms.CharField(label='To',widget=forms.TextInput(
attrs={'placeholder': 'Enter phone number, contact or group (add as many as you like)'}))
Then the normal rendering (using the Bootstrap templates) is,
<div id="div_id_recipients" class="control-group">
<label for="id_recipients" class="control-label requiredField">
To<span class="asteriskField">*</span>
</label>
<div class="controls">
<input class="textinput textInput" id="id_recipients" name="recipients" placeholder="Enter phone number, contact or group (add as many as you like)" type="text">
</div>
</div>
What I want to do is have some extra HTML appear just before the final closing div. So it would look like,
<div id="div_id_recipients" class="control-group">
<label for="id_recipients" class="control-label requiredField">
To<span class="asteriskField">*</span>
</label>
<div class="controls">
<input class="textinput textInput" id="id_recipients" name="recipients" placeholder="Enter phone number, contact or group (add as many as you like)" type="text">
</div>
<div class="controls-aside">
<button type="button" class="btn">Address Book</button>
<button type="button" class="btn">Add Contact</button>
</div>
</div>
I know that I can replace the existing template for this field with a custom template but I want to be able to re-use their template without doing a copy/paste since that makes it not very maintainable.
So what is the best way to implement this? I also want to add an extra class to the label if anyone can suggest how to do it?
For completeness, but not for your case: even after layout creation, Layout.wrap('recipients', Div) will work if one only needs to wrap a control into an additional Div.
About adding HTML inside the layout. Last hour I needed a very custom HTML, so did this:
(formatting)
i = self.helper.layout.fields.index('guest_email')
self.helper.layout.insert(
i+1,
HTML('{}'.format(
reverse_lazy('invite_guests'),
_('Invite to a party'))
))
I came here googling for a HTMLWrapper class example for Crispy Forms, so that I could do a prettier thing instead:
self.helper['guest_email'].wrap(HTMLWrapper(
'guest_email',
before='',
after='{}'.format(href, title))
If I end up creating one, I'll get back and post it.
For me it worked that way:
from crispy_forms.layout import Field, HTML
self.helper["some_field_name"].wrap(Field, HTML("<p>Example</p>"))
The benefit of using HTML is that it also gives you the possibility to use context variables.

Bootstrap 3 - Form horizontal not working

I'm using Django with CrispyForms and I'm updating an old project of mine to BS3.
The only thing I didn't find out how to adapt are form-horizontal. My forms used to look like this:
Now the label is always on top of the input - like it was before with form-vertical.
I read some posts on Stack, googled around but nobody has a working crispy answer for me!
The weirdest thing is that the Bootstrap guys say that they did not change or remove this class.
Any ideas what I can do to get my old, lovely horizontal` forms back?
Thanks!
Update:
CrispyForms produces the following, even with bootstrap3 as template pack:
<div class="form-group" id="div_id_title">
<label class="control-label requiredField" for="id_title">Titel
<span class="asteriskField">*</span>
</label>
<div class="controls ">
<input type="text" name="title" maxlength="65" id="id_title" class="textinput textInput form-control">
</div>
</div>
Take a look here:
http://django-crispy-forms.readthedocs.org/en/latest/crispy_tag_forms.html#bootstrap3-horizontal-forms
You should add
helper.label_class = 'col-lg-x' #for example 'col-lg-2'
helper.field_class = 'col-lg-x' #for example 'col-lg-10'
BS3 has a 12 column grid system, more info about that here
http://getbootstrap.com/css/#grid
That made the form horizontal but unfortunately the labels align to the left, I'm trying to fix that now.
UPDATE: If you have issues with the vertical spacing between the fields add a row css class to the outer div of every field, the html output:
<div class="form-group row" id="div_id_title">
###labels HTML###
</div>
Probably a bug on the field.html template for bootstrap3.
Did you put the form-control inside form-group?
<form class="form-horizontal" role="form">
<div class="form-group">
<label lass="col-sm-2 control-label">Password</label>
<div class="col-sm-10">
<input type="password" class="form-control" id="inputPassword" placeholder="Password">
</div>
</div>..
</form>
Demo: http://bootply.com/104095
I spent a few hours trying to figure this out. For me, this worked. You have to go into the project settings.py and add the line:
CRISPY_TEMPLATE_PACK = 'bootstrap3'
After searched thru the docs, I ended up find that I had to do this in the crispy-forms source code itself:
if (
TEMPLATE_PACK == 'bootstrap3'
and not is_checkbox(field)
and not is_file(field)
):
css_class += ' form-control'

Django Upload From Template

I am looking into uploading a file from the html template. I've seen a fair amount of documentation including FileFields, ImageFields etc. However, ideally I do not want to rewrite my code.
Currently, I have a simple form on my template and I would like to have an upload function there, where, an image will be uploaded and stored into my applications media folder and if possible added to a database.
I do know that I've probably taken a long and complex route but if anyone can help it'll be great!
html.py:
<div class="row"> <div class="span1 offset5"> </bR>
<form class="form-horizontal" method="get" action="/add/submit" value="add">
<fieldset> <div class="input">
<div class="inline-inputs">
<label>Ride Name:</label><input type="text" name="name">
<label>Type:</label><input type="text" name="type">
<label>Theme:</label><input type="text" name="theme">
<label>Description:</label><textarea rows="5" name ="description"></textarea>
<label>Author:</label><input type="text" name="author">
<label>Date Released:</label>
<div id="datetimepicker" class="input-append date">
<input type="text" name="date"></input>
<span class="add-on">
<i data-time-icon="icon-time" data-date-icon="icon-calendar"></i>
</span>
</div>
<label>Thread:</label><input type="text" name="thread">
<label>Video</label><textarea rows="2" name ="video"></textarea>
<br><br>
<input class="btn btn-primary" type="submit" value="Add" />
</div> </div>
</fieldset>
</form>
</div> </div>
Currently my Views.py just takes the entered data and inserts it into a database. I want to add the ability for a file to be uploaded:
def Ride_Add_Submit(request):
name = request.GET['name']
type = request.GET['type']
theme = request.GET['theme']
description = request.GET['description']
author = request.GET['author']
releasedate=request.GET['date']
video=request.GET['video']
thread=request.GET['thread']
entry = RollerCoaster(name=name, type=type, theme=theme, description=description, releasedate=releasedate, author=author, video=video, thread=thread)
entry.save()
return TemplateResponse(request, 'Ride_Add.html')
I don't understand why you keep talking about the template here, the template has nothing whatsoever to do with anything. The handling of the upload, like all logic, is done in the view.
The file upload overview still has all the information you need. You can ignore the parts about the Django form and checking if it's valid, and simply pass the file object to your upload handling function, which that page also explains.
However you will need to change your template so that the form element uses POST instead of GET (which is almost certainly a good idea anyway), and use enctype="multipart/form-data" as also described on that page.
Finally, I really would advise you to rewrite your code to use ModelForms. Not only would it make your code much simpler, it would also do things like validate the entry to make sure all the required fields are present and are of the right types, and so on - as well as output valid HTML (for instance, you're missing for attributes in your label tags).