Passing Keyboard event not working iOS simulator/device from WebDriver - iphone

Scenario:
- We have registration form that checks for errors via AJAX
- Fields are: email, confEmail, fname, lname, pwd, confPwd
- Error check happens when user enters in "email" field and tabs to "confEmail" field. Same for "pwd" and "confPwd" field
- I am trying to write automation script that mimics user behavior where user will enter "test" in "email" field and then tab to next field which is "confEmail". This should invoke AJAX check and throw error about "invalid email address"
Test configuration:
- Test written in Linux
- Running in iPhone simulator on Mac (of course)
This piece of code enters email address:
driver.findElement(By.cssSelector(Locators.getLocator("mobilebuy->emailAddressField"))).sendKeys("test");
Since sendKeys will not move focus away from that field, I then send TAB/click to next field so that the AJAX fires up. Apparently, doing that doesn't work. The AJAX never fires and no error message shows up. I can see when I simulate this manually in iPhone simulator, it works.
This should tab to next field:
driver.findElement(By.cssSelector(Locators.getLocator("mobilebuy->emailAddressField"))).sendKeys(Keys.TAB);
OR
This should click on next field which should fire AJAX:
driver.findElement(By.cssSelector(Locators.getLocator("mobilebuy->confEmailAddressField"))).click();
ANY IDEA ON HOW TO PROCEED WITH THIS ISSUE? I LOOKED THROUGH IT CLOSELY AND EVEN TRIED TO PASS IN UNICODE FOR "TAB" KEY BUT THAT DIDN'T WORK EITHER.

First of all, only the FirefoxDriver supports Action class (according to http://code.google.com/p/selenium/wiki/TipsAndTricks), but you should also expect support for the InternetExplorerDriver too.
Got this to work using following steps:
- I have a Type method which types items into the form
- Thereafter, I send a click to the field that fires Ajax using Action class and that seemed to work
// (WebDriver, email, confEmail, fname, lname, pwd, confPwd)
TypeRegistrationData(driver, "test/tester#com", "", "", "", "", "");
// action builder that tabs to next field
WebElement we = driver.findElement(By.cssSelector(Locators.getLocator("buy->emailAddressField")));
Actions builder = new Actions(driver);
builder.click(we); // this fires up the ajax that is expected

Try using Actions chain
Actions builder = new Actions(driver);
builder.keyDown(Keys.TAB).keyUp(Keys.TAB);
builder.build().perform();
If I were really desperate I would try to use sendKeys not necessarily on the text fields but on some parent element (could be even on body itself).

Related

Play - Custom validations with custom error message

I am using the Play framework in Scala to develop a small blog website. I currently have a form (successfully) set up for an easy registration of users. This login page just accepts a username (ie. no password yet), verifies that is of the appropriate length and doesn't exist yet, and adds this user to the database (currently still in memory). Length can be verified using just the basic form functionality, however, the uniqueness of this username required me to use custom validations.
Now, this all works, except for the custom error message. When a normal form requirement is not fulfilled, an error message is returned and displayed in the view (eg. "The minimum length is: 5"). I want to display a similar message when the name is not unique. In the first link I provided there is an example of custom validations which seems to have an argument that represents such custom error message for validations you write of your own. However, this does not display in the view, while the others do.
Current validation code:
private val myForm: Form[Account] =
Form(mapping("name" -> text(3, 24))(Account.apply)(Account.unapply).verifying(
"Account is not in the DB.",
fields =>
fields match {
case data: Account => accountExists(data.name).isDefined
}
)
)
Anyone has any ideas?

Testing stateful Mojolicious apps

I want to test hiding and unhiding of an entry. I conduct the following tests in Mojolicious t/basic.t:
my $t = Test::Mojo->new('AdminApi');
$t->get_ok('/publications/hide/1');
$t->get_ok('/read/publications/meta')->content_unlike(qr/Paper with id 1:/i);
$t->get_ok('/read/publications/meta/1')->content_like(qr/Cannot find entry id: 1/i);
$t->get_ok('/publications/unhide/1');
$t->get_ok('/read/publications/meta')->content_like(qr/Paper with id 1: <a href/i);
$t->get_ok('/read/publications/meta/1')->content_unlike(qr/Cannot find entry id: 1/i);
My problem is that the two lines '/publications/hide/1' and '/publications/unhide/1' do not hide and unhide the entry. The state of the entry remains untouched.
If I repeat the steps manually in the browser everything works well. For the obvious reasons I want to have it automated with the tests. How to do this?
EDIT: The calls '/publications/hide/1' and '/publications/unhide/1' change the state of the database - just a simple UPDATE query. The change applies to the whole application - for all users. But one needs to be logged in as a user to hide/unhide. Question: how do I emulate a logged user during the test?
Contents generated by '/read/publications/meta' and '/read/publications/meta/1' can be read without login.
Bitbucket Repo
File with test code: basic.t
As you have already said, you need to be logged in to perform the hide and unhide action.
my $t = Test::Mojo->new('AdminApi');
You are creating a new UserAgent here. The Test::Mojo class inherits from Mojo::UserAgent. It has a cookie_jar and thus keeps a session alive. You need that to perform this action:
$t->get_ok('/publications/hide/1');
But right now you are not logged in. What you need to do is log in the user. Looking at the code in your repository, you actually assert that you are not logged in.
$t->get_ok('/')->status_is(200)->content_like(qr/Please login or register/i);
Before you perform the hide, you need to log in the user. After digging a bit in your code I found the action and the template to do that, so I know what the request needs to look like.
$t->post_ok(
'/do_login' => { Accept => '*/*' },
form => { user => 'admin', pass => 'hunter2' }
);
Now your $t UserAgent should be logged in and you can do the hide. Note that get_ok only checks if there was no transport error. So in fact it would make sense to now check if in fact you are now logged in.
You could do that by introspecting the session in the application, by checking the logfile (you are writing "Login success" there) or by checking the page for some string that says that the user is logged in. In templates/display/start.html.ep there is a text that welcomes the logged-in user, so you can use that.
$t->post_ok(
'/do_login' => { Accept => '*/*' },
form => { user => 'admin', pass => 'hunter2' }
)->text_like(qr/Nice to see you here admin/i);
Because text_like uses the text-nodes, the <em> around the username is not relevant in the test.
Right, now we know you are logged in. Time to switch the thing on and off.
$t->get_ok('/publications/hide/1');
Because there is no obvious error thrown for that as far as I can tell, I don't see how to test the success of that. Status code is one way, but there might be something in the content as well that you could test.
To verify the state of the application, you would now call the publication.
$t->get_ok('/read/publications/meta')->content_unlike(qr/Paper with id 1:/i);
$t->get_ok('/read/publications/meta/1')->content_like(qr/Cannot find entry id: 1/i);
Right. But remember, our $t is still logged in. Maybe the logged-in user is allowed to see hidden stuff as well as unhidden stuff. Maybe they are not.
It's probably safer to make a second UserAgent that's not logged in, and check with that one as well.
# check with an unauthorized user
my $t_not_logged_in = Test::Mojo->new('AdminApi');
$t_not_logged_in
->get_ok('/read/publications/meta')
->content_unlike(qr/Paper with id 1:/i);
$t_not_logged_in
->get_ok('/read/publications/meta/1')
->content_like(qr/Cannot find entry id: 1/i);
Now basically you repeat the same thing by unhiding your content and testing again. Rinse and repeat.
Keep in mind that unless you are using an explicit testing database (which you seem not to do), you cannot be sure that there even is an entry 1. Or what the name of that is. You should use fixtures for the tests. You could, for example, create a fresh instance of the DB using sqlite and work with that.

How to keep the value in a field from the inputPassword helper in the Play framework?

Excuse me if the answer is obvious but whilst I know Java I am very new to Scala, the Play framework and general web app development.
I have taken on a project that has a view where you can set up some database connection details that includes fields such as database name, username, password etc. At present the code uses the Play input helper 'inputText' and so the password field shows the password in plain text. I need to fix this and so have changed it to use the 'inputPassword' helper however whenever I visit this page in my app to edit one of the other fields the password field has not been populated with the password so the user needs to re-enter it in order to save, I do not want to have to do this.
The password populated when it was an inputText helper so I can only assume that there's something in the inputPassword helper that stops the value from populating in the form, maybe it expects the password field to only be used when inputting a new one? Is there a way to override this and have it fill in the on screen form with the password so the user does not have to re-enter in order to change another field on the page?
This is the old version in my view
#inputField(form("password"), '_label -> "Password", '_labelwidth -> "2", 'class -> "form-control", '_type -> "password", '_single -> false)</code>
This is the new version
#inputPassword(form("password"), '_label -> "Password", '_labelwidth -> "2", 'class -> "form-control", '_single -> false, '_type -> "password")
I then have an the templates inputField.scala.html which contains #helper.inputText(field, args:_*) and the inputPassword.scala.html which contains #helper.inputPassword(field, args:_*)
I tried adding 'value -> form("password").value to the parameters in the inputPassword version and whilst this displayed something in stars in the password field the credentials were incorrect so it cannot have been the correct information.
Any help or suggestions are appreciated, even if it is to just understand why inputText populates the field whereas inputPassword does not. The only other way I can think of to do this is possibly to have the password as a separate form on the same page and make it so the password entry is only mandatory when using the page for the initial set up of the database credentials and optional on the edit page.
I don't think it's really necessary to send password values back and forth for security reasons. As an internet user I've never seen form with filled password.
Regarding your case I see two options:
Either separate password change into another form (but this is usually an option if you have more sophisticated password reset process, like two-step verification)
Or apply the following password validation logic on the server: leave the password unchanged if it is empty

Magento email bouncing back as no email address

I have a 'guest' checkout option on a Magento store, whenever I complete a transaction the "Order Confirmation" email that it sends out is always being returned.
Obviously the email address itself is being saved in the onepage checkout (otherwise the inline validation will display errors).
On the sales_flat_order table I can see the following columns are all NULL after an order has been placed:
customer_email,
customer_firstname,
customer_lastname
The odd thing is on the vagrant box (which should be near enough identical) the 3 columns above all have values in them when I go through the exact same process.
I cannot be sure what is happening, but in a nutshell it would seem that this customer_email for whatever reason isn't be saved to the sales_flat_order table & in turn causing this email to return as undelivered.
Can anyone point me in the right direction of where the logic is for the 'Order Confirmation' email can be found within the Magento system?
I fixed it - there was a core file that had been edited and was setting this customer email value to null...
Order.php from app/code/core/Mage/Sales/Model/ to app/code/local/Mage/Sales/Model/
And
create function getCustomerEmail() and code this function
public function getCustomerEmail() {
if(empty($this->getCustomerEmail())) {
$this->setCustomerEmail($this->getBillingAddress()->getEmail());
} else {
$this->setCustomerEmail($this->getCustomerEmail());
}
}

GAS - setTag() - getTag() still not working

I'm creating a webapp which allow :
to log using data stored in a spreadsheet (login and password)
to add some data to this spreadsheet (bet on rubgy matchs)
My problem is to recognize which user is connected.
What i did so far
in the doGet function, where all panels except connection are invisible, I created a label where i'll store the login into the tag
var loginlabel=app.createLabel().setId('loginlabel').setText('test').setVisible(true);
in the connection, I store the login into a invisible label tag
var logintest=e.parameter.logint;
app.getElementById('loginlabel').setTag(logintest);
I want to allow people to change their own password (but I also need to retrieve the login name for other purposes, but let's take this one
When I click on "Modify password" button, I want to get the Tag, but I always get a NULL
var login=app.getElementById('loginlabel').getTag();
I'm free to share my code here or wherever
Maybe it does exist other way to do this, I'm open for advice
In a server handler you can get the tag value using
var tagValue = e.parameter.loginlabel_tag ; // assuming the label has a name = 'loginlabel'
Note that the widget must have a name to be able to retrieve the tag value (see this post among others)