2

I am writing regression tests for a web application using robot framework and the Selenium2Library library. I have a simple test which changes all of the fields of an "account settings" type form (think username, password, email, etc.), then revisits the page and makes sure all of the data was saved. Like so:

*** Test Cases ***
Sample Test
    Change All Account Details
    New Account Details Should Be Saved

*** Keywords ***
Change All Account Details
    Navigate to Account Page
    Input Text    accountSettingFrom_firstname    Test
    Input Text    accountSettingFrom_lastname    Dummy
    Input Text    accountSettingFrom_email    new_email@example.com
    # etc etc, eventually save the form

New Account Details Should Be Saved
    Go To    ${ACCOUNT_URL}
    Textfield Value Should Be    accountSettingFrom_firstname    Test
    Textfield Value Should Be    accountSettingFrom_lastname    Dummy
    Textfield Value Should Be    accountSettingFrom_email    new_email@example.com

I get the following error on the final step (Textfield Value Should Be accountSettingFrom_email new_email@example.com) when running this test: Value of text field 'accountSettingFrom_email' should have been 'new_email@example.com' but was 'None'

I have taken screenshots the moment before that step runs, and I have added a pause and manually confirmed that the value attribute of 'accountSettingFrom_email' is indeed 'new_email@example.com'. HTML of the element at time the check occurs:

<input type="email" name="accountSettingFrom[email]" value="new_email@example.com" class="foo bar" required="required" tabindex="3" maxlength="128" url="/foo/bar" userid="foobar" id="accountSettingFrom_email">

You'll notice that the first two Textfield Value Should Be keywords pass. The only difference I can discern between the three elements is that 'accountSettingFrom_email' is type="email" instead of type="text", but if the the keyword is successfully locating the element, then why can't it grab the value of the value attribute?

So am I doing something wrong? I feel like this or some similar keyword must exist to test this, without having to resort to writing a custom library.

fildred13
  • 2,280
  • 8
  • 28
  • 52
  • What exactly the code looks like? Are you getting the value of the email field? – Saifur Dec 09 '15 at 02:03
  • Well all of the code I have written is exactly represented here (excluding the library imports and such, which obviously are working or else the whole thing would just not work). The python bindings of selenium for "Textfield Value Should Be" is part of Selenium2Library, which I cannot control since it is a third-party library. The keyword in theory SHOULD be returning the value of the email field, but isn't. And that is more or less the question: why not? The documentation of Selelnium2Library seems to suggest that this should work. – fildred13 Dec 09 '15 at 02:08
  • 1
    Its possible that there is a hidden input with the same name. Look at HTML or see if this passes: Xpath Should Match X Times //input[@name='accountSettingFrom_email' or @id='accountSettingFrom_email'] 1. I have seen pages with multiple elements with the same id (invalid HTML). – ombre42 Dec 09 '15 at 18:26
  • Good suggestion, especially considering the developers working on this project are prone to duplicate id's and we've been hunting them down piece by piece. Unfortunately (odd that I'm saying this), there are no duplicate IDs on this page. How I wish that was the problem, though. – fildred13 Dec 09 '15 at 22:03

2 Answers2

5

You have hit some bugs in Selenium2Library. When Selenium2Library was created, HTML5 was not ratified. Internally the library is filtering out your element because it has a type other than 'text' (made sense before HTML5). Textfield Value Should Be can only find your element if it has tag name input and attribute value 'text' for type. See https://github.com/robotframework/Selenium2Library/issues/546

Also due to how Textfield Value Should Be is implemented, the error you are getting makes you think the element was found when in fact it was not because it was filtered out. See https://github.com/robotframework/Selenium2Library/issues/547

In contrast, Input Text and Input Password have never filtered on element tag or attribute.

ombre42
  • 2,344
  • 15
  • 21
  • I was imagining something like this was going on, but I wasn't sure. Thanks a lot for clarifying, and I'll be sure to follow those bug reports. – fildred13 Dec 10 '15 at 20:10
0

I would try Get Element Attribute instead to get the attribute named value instead. According to the API it should be

accountSettingFrom_email@value

Saifur
  • 16,081
  • 6
  • 49
  • 73
  • There is the even more direct keyword "Get Value", but this feels like a work around, to me. I am looking for someone with experience with Selenium2Library to explain why the "Textfield Value Should Be" - which should read the value of input elements - is incorrectly reading the value in this case. Using Get Value and comparing it to the expected with a few more keywords just feels too much like a hack. I would sooner write my own library file to keep "complicated" logic out of the keywords area. – fildred13 Dec 09 '15 at 02:28
  • You can certainly do that. But, so far I know about the core Selenium library that the proper value and attribute value is treated differently. I am little suspicious that you need to read the attribute not the property. See [this](http://stackoverflow.com/questions/6003819/properties-and-attributes-in-html). And, I do not see this API as workaround by the way – Saifur Dec 09 '15 at 02:33
  • If your suspicions are true, then why do the two preceding lines ( such as `Textfield Value Should Be accountSettingFrom_firstname Test`) pass? The keyword, in that case, successfully grabs and tests the value of the element, which is precisely what the keyword is meant to do. I don't understand why it would work on one element, and not another, in what appears to be the exact same situation. – fildred13 Dec 09 '15 at 02:37
  • I don't know. In general these fields seem same but `type=email` is a special type in [HTML5](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input) which has some inbuild mechanism to manipulate the value and checking the validation before submit. – Saifur Dec 09 '15 at 02:42
  • For posterity, I am currently using the Get Value keyword and comparing that to the expected value with the Should Be Equal keyword. Saifur's suggestion is also completely valid, the Get Value keyword is just slightly more succinct. I am accepting this answer because it DOES answer the question of how to do it. I will have to ask another, more specific question about why exactly the most direct keyword (Textfield Value Should Be) is not working. – fildred13 Dec 09 '15 at 22:06