My UI is written in pyforms.
How can I implement a password field? (EG. instead of 'P#ssW0rd' it would display '********').
I have found that I can utilize QLineEdit.EchoMode, but unsure how to implement.
Thanks in advance!
Updated to reflect community guidelines
Pyforms also includes a password box. You can also use
self._password = ControlPassword('Password')
So simply:
import pyforms
from pyforms.basewidget import BaseWidget
from pyforms.controls import ControlText
from pyforms.controls import ControlButton
from pyforms.controls import ControlPassword
class Login(BaseWidget):
def __init__(self):
super(Login,self).__init__('Simple example 1')
#Definition of the forms fields
self._username = ControlText('Username', 'Default value')
self._password = ControlPassword('Password')
self._button = ControlButton('Login')
self._button.value = self.__buttonAction #Define button action
def __buttonAction(self):
"""Button action event"""
username = self._username.value
password = self._password.value
credentials = (username, password)
return credentials
#Execute the application
if __name__ == "__main__":
pyforms.start_app( Login )
You can add the following module as ControlPasswordText.py in your project folder:
from pysettings import conf
from pyforms.Controls import ControlText
from PyQt4.QtGui import QLineEdit
class ControlPasswordText(ControlText):
def __init__(self, *args, **kwargs):
super(ControlPasswordText, self).__init__(*args, **kwargs)
self.form.lineEdit.setEchoMode(QLineEdit.Password)
And here's how you would use it:
import pyforms
from pyforms import BaseWidget
from pyforms.Controls import ControlText
from pyforms.Controls import ControlButton
# Importing the module here
from ControlPasswordText import ControlPasswordText
class SimpleExample1(BaseWidget):
def __init__(self):
super(SimpleExample1,self).__init__('Simple example 1')
#Definition of the forms fields
self._username = ControlText('Username')
# Using the password class
self._password = ControlPasswordText('Password')
#Execute the application
if __name__ == "__main__": pyforms.startApp( SimpleExample1 )
Result:
Related
I've been stuck on this problem for a couple hours. I'm new to django and automated testing, and I've been playing around with Selenium and django's StaticLiveServerTestCase. I've been trying to test my login form (which works fine when I use runserver and test it myself, by the way.)
Everything is working great, except I can't seem to successfully login my test user. I've narrowed down the break point to django's User.authenticate method.
The User object is created successfully in my setUp and I can confirm that by accessing it's attributes in my test method. However, authenticate fails.
I've looked at the following for help but they didn't get me very far:
Django Unittests Client Login: fails in test suite, but not in Shell
Authentication failed in Django test
Any idea why authenticate fails? Do I need to add something to my settings?
from django.contrib.staticfiles.testing import StaticLiveServerTestCase
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from django.contrib.auth.models import User
from django.contrib.auth import authenticate
class AccountTestCase(StaticLiveServerTestCase):
def setUp(self):
self.selenium = webdriver.Chrome()
super().setUp()
User.objects.create(username='test', email='test#test.com', password='Test1234', is_active=True)
def tearDownClass(self):
self.selenium.quit()
super().tearDown()
def test_register(self):
user = authenticate(username='test', password='Test1234')
if user is not None: # prints Backend login failed
print("Backend login successful")
else:
print("Backend login failed")
user = User.objects.get(username='test')
print(user)
print(user.username) # prints test
print(user.password) # prints Test1234
I found the issue. The User.authenticate() method hashes the password provided. However, I set the password directly when creating the user, which means it was stored as Test1234, so the hashed password provided during authentication did not match 'Test1234', hence the failure.
To properly store a hashed password, you need to use the set_password() method.
Updated setUp code:
def setUp(self):
self.selenium = webdriver.Chrome()
super().setUp()
user = User.objects.create(username='test', email='test#test.com', is_active=True)
user.set_password('Test1234')
user.save()
Using create_superuser resolved the issue. Below code resolves it.
from django.contrib.auth.models import User
from django.contrib.staticfiles.testing import StaticLiveServerTestCase
from django.test import Client
from selenium.webdriver.common.by import By
from selenium.webdriver.firefox.webdriver import WebDriver
import time
from django.contrib.auth import authenticate
#from apps.digital.models import User
class MyTests(StaticLiveServerTestCase):
port = 0
host = 'my host'
def setUp(self):
super(MyTests, self).setUp()
self.selenium = WebDriver()
self.client = Client()
self.user = User.objects.create_superuser(username='test', password='Test1234', email='test#test.com', is_active=True)
self.user.save()
def tearDown(self):
self.selenium.quit()
super(MyTests, self).tearDown()
def test_login(self):
self.user = authenticate(username='test', password='Test1234')
if self.user is not None: # prints Backend login failed
self.user = User.objects.get(username='test')
print(self.user.username) # prints test
print(self.user.password) # prints Test1234
self.login = self.client.login(username='test', password='Test1234')
self.assertEqual(self.login, True)
print("Backend login successful")
self.selenium.get('%s%s' % (self.live_server_url, '/admin/'))
username_input = self.selenium.find_element_by_name("username")
username_input.send_keys(self.user.username)
password_input = self.selenium.find_element_by_name("password")
password_input.send_keys('Test1234')
self.selenium.find_element_by_xpath('//input[#value="Log in"]').click()
time.sleep(1)
else:
print("Backend login failed")
User Authentication is getting passed but when I try to login with the same credentials, the login fails.
from django.contrib.auth.models import User
from django.contrib.staticfiles.testing import StaticLiveServerTestCase
from django.test import Client
from selenium.webdriver.common.by import By
from selenium.webdriver.firefox.webdriver import WebDriver
import time
from django.contrib.auth import authenticate
#from apps.digital.models import User
class MyTests(StaticLiveServerTestCase):
port = 0
host = '<my host>'
def setUp(self):
super(MyTests, self).setUp()
self.selenium = WebDriver()
self.client = Client()
self.user = User.objects.create(username='test', email='test#test.com', is_active=True)
self.user.set_password('Test1234')
self.user.save()
def tearDown(self):
self.selenium.quit()
super(MyTests, self).tearDown()
def test_login(self):
self.user = authenticate(username='test', password='Test1234')
if self.user is not None: # prints Backend login failed
self.user = User.objects.get(username='test')
print(self.user.username) # prints test
print(self.user.password) # prints Test1234
self.login = self.client.login(username='test', password='Test1234')
self.assertEqual(self.login, True)
print("Backend login successful")
self.selenium.get('%s%s' % (self.live_server_url, '/admin/'))
username_input = self.selenium.find_element_by_name("username")
username_input.send_keys(self.user.username)
password_input = self.selenium.find_element_by_name("password")
password_input.send_keys('Test1234')
self.selenium.find_element_by_xpath('//input[#value="Log in"]').click()
time.sleep(1)
else:
print("Backend login failed")
i dont know why this is happening but i have tried alot but still i m getting the same output in my browser..
i m running this code here i am trying to inherit the handle class instances to my another class.. i am running my code in using google app engine in chrome browser.. whole process is similar as show by udacity instructor else the rot13 code ..
import os
import codecs
import webapp2
import jinja2
#from check import valid_month
#from check import valid_year
#from check import valid_day
template_dir = os.path.join(os.path.dirname(__file__),'templates')
jinja_env = jinja2.Environment(loader = jinja2.FileSystemLoader(template_dir),
autoescape= True)
class Handler(webapp2.RequestHandler):
"""docstring for Handler"""
def write(self, *a, **kw):
self.response.out.write(*a, **kw)
def render_str(self, template, **params):
t = jinja_env.get_template(template)
return t.render(params)
def render(self,template,**kw):
self.write(self.render_str(template, **kw))
class Secondhandler(Handler):
def get(self):
key = self.request.get_all("name")
name = ''.join(key)
new = codecs.encode(name, 'rot13')
self.render("shopping_list.html", name = new )
app = webapp2.WSGIApplication([
('/',Handler)
], debug=True)
as you can see my second handler is named secondhandler which inherit from its parent class named handler..
but when i view this in my browser it throws an error , my shopping list.html is as follows
<form>
<h2>tell us what you like</h2>
<br>
<textarea name='name' type='text'>{{name}}</textarea>
<br>
<br>
<button>add</button>
</form>
most important thing is that i dont think tht there is any indentation issue as when i run my code by using the whole get in just main handler it works fine ..
but still i am unable to use secondhanlder .. heres my code without class secondhandler .. and it prints and works rot13 nicely..
import os
import codecs
import webapp2
import jinja2
#from check import valid_month
#from check import valid_year
#from check import valid_day
template_dir = os.path.join(os.path.dirname(__file__),'templates')
jinja_env = jinja2.Environment(loader = jinja2.FileSystemLoader(template_dir),
autoescape= True)
class Handler(webapp2.RequestHandler):
"""docstring for Handler"""
def write(self, *a, **kw):
self.response.out.write(*a, **kw)
def render_str(self, template, **params):
t = jinja_env.get_template(template)
return t.render(params)
def render(self,template,**kw):
self.write(self.render_str(template, **kw))
def get(self):
key = self.request.get_all("name")
name = ''.join(key)
new = codecs.encode(name, 'rot13')
self.render("shopping_list.html", name = new )
#class Secondhandler(Handler):
app = webapp2.WSGIApplication([
('/',Handler)
], debug=True)
It doesn't look like you've registered SecondHandler:
app = webapp2.WSGIApplication([
('/',Handler)
], debug=True)
What happens when you change Handler in that block to SecondHandler instead?
I've created the tests folder, written my first test that should open a browser, point to a page and login, then go to home page.
Test run and fail, as expected, but I can't find out why.
browser should be available, pytest-selenium is installed by pip.
import pytest
from django.contrib.auth.models import Group, Permission, User
from django.test import TestCase, RequestFactory
class CreaPageTest(TestCase):
def setUp(self):
self.factory = RequestFactory()
def test_homepage(self):
request = self.client.get('/new')
request.user = self.user
self.assertEqual(request.status_code, 200)
def test_login(self):
request = self.client.get('/per/login')
username_field = self.browser.find_element_by_name('username')
username_field.send_keys('peppa')
password_field = self.browser.find_element_by_name('password')
password_field.send_keys('pig')
password_field.send_keys(Keys.RETURN)
test_homepage()
> username_field = self.browser.find_element_by_name('username')
E AttributeError: 'CreaPageTest' object has no attribute 'browser'
tests/test_ore_app_views.py:27: AttributeError
what am I missing?
Any advice to examples of this kind of test is really appreciated.
You should configure self.browser inside setUp function. You are also missing an import for Keys. Code should be like this.
import pytest
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from django.contrib.auth.models import Group, Permission, User
from django.test import TestCase, RequestFactory
class CreaPageTest(TestCase):
def setUp(self):
self.factory = RequestFactory()
self.browser = webdriver.Firefox()
Also please refer to the docs, here http://selenium-python.readthedocs.org/getting-started.html
hi recently I have implemented a temp django model and I want this to get populate when the user clicks it from django admin
this is the implementation in django admin
from django.contrib import admin
from polls.models import Poll
from polls.models import TempModel
from django.conf.urls import patterns
from django.http import HttpResponse
from test_data import TestData
from django.http import HttpResponse
from django.template import RequestContext, loader
from test_data import TestData
class TempModelAdmin(admin.ModelAdmin):
fields = ('permalink', )
def test(self):
x = TestData.get_test_data()
admin.site.register(Poll)
admin.site.register(TempModel, TempModelAdmin)
and this is the temporary class which I used to populate data
from models import TempModel
class TestData(object):
#classmethod
def get_test_data(self):
print "**********************************************"
print "get test data"
print "**********************************************"
list = []
for x in range(0,50):
str_val = str(x) + "djdj;djfhdfjiosdifj";
list.append(str_val)
temp_model = TempModel()
temp_model.permalink = str_val
temp_model.save()
print "=============================================="
print "Object Count"
print TempModel.objects.count()
print "=============================================="
return list
this is not getting called . Can anyone know the reason for this ?
Thank you in advace
You're making a class method with self, it takes an instance of type. Try changing method signature:
def get_test_data(cls):
I figured it out by doing this approach and it worked
class TempModelAdmin(admin.ModelAdmin):
fields = ('permalink', )
def __init__(self, *args, **kwargs):
super(TempModelAdmin, self).__init__(*args, **kwargs)
self.my_method()
def my_method(self):
print "*************----------------------------"
TestData.get_test_data()
I did a recaptcha integration using the following django snippet
settings.py
RECAPTCHA_PUBLIC_KEY = '<your public key>'
RECAPTCHA_PRIVATE_KEY = '<your private key>'
#widgets.py
from django import forms
from django.utils.safestring import mark_safe
from django.conf import settings
from recaptcha import captcha
class ReCaptcha(forms.widgets.Widget):
recaptcha_challenge_name = 'recaptcha_challenge_field'
recaptcha_response_name = 'recaptcha_response_field'
def render(self, name, value, attrs=None):
return mark_safe(u'%s' % captcha.displayhtml(settings.RECAPTCHA_PUBLIC_KEY))
def value_from_datadict(self, data, files, name):
return [data.get(self.recaptcha_challenge_name, None),
data.get(self.recaptcha_response_name, None)]
#fields.py
from django.conf import settings
from django import forms
from django.utils.encoding import smart_unicode
from django.utils.translation import ugettext_lazy as _
from marcofucci_utils.widgets import ReCaptcha
from recaptcha import captcha
class ReCaptchaField(forms.CharField):
default_error_messages = {
'captcha_invalid': _(u'Invalid captcha')
}
def __init__(self, *args, **kwargs):
self.widget = ReCaptcha
self.required = True
super(ReCaptchaField, self).__init__(*args, **kwargs)
def clean(self, values):
super(ReCaptchaField, self).clean(values[1])
recaptcha_challenge_value = smart_unicode(values[0])
recaptcha_response_value = smart_unicode(values[1])
check_captcha = captcha.submit(recaptcha_challenge_value,
recaptcha_response_value, settings.RECAPTCHA_PRIVATE_KEY, {})
if not check_captcha.is_valid:
raise forms.util.ValidationError(self.error_messages['captcha_invalid'])
return values[0]
#forms.py
class RegistrationForm(forms.Form):
...
recaptcha = marcofucci_fields.ReCaptchaField()
...
But I have the forms defined in the django forms wizard and it calls the clean method on the field twice, even if the captcha is included in the last form.
As in the following:
from registration.forms import RegistrationWizard,RegistrationForm,ProfileForm
url(r'^register/$',
RegistrationWizard([RegistrationForm,ProfileForm]),
name='register_wizard'),
How do I circumvent this situation. What is the need to call the clean on the last form twice?
If a form is bound, it will allways call clean when renderering (even if you don't call form.is_valid).
You might want to consider using this instead:
django snippet 1644