Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't set value of Input Element #20

Open
BradVanDuker opened this issue Mar 18, 2019 · 14 comments
Open

Can't set value of Input Element #20

BradVanDuker opened this issue Mar 18, 2019 · 14 comments

Comments

@BradVanDuker
Copy link

BradVanDuker commented Mar 18, 2019

I'm not sure if this is a bug or not, but the behavior seems inconsistent.
Elements Input and Text_Field share a value attribute, but only the latter element can set it.

Meta -

Nerodia Version: 0.11.0
Selenium Version: 3.141.0
Browser Version: firefox
Browser Driver Version:
OS Version: Windows 10 Pro

Expected Behavior -

For more consistency Value should be a settable value

Actual Behavior -

Input.value can't be set.
Input.set() doesn't exist

If handled as a text field, things work fine. Both share the 'value' attribute.

Steps to reproduce -

input = browser.input(name='title')
input
#<Input: located: False; {'name': 'title', 'tag_name': 'input'}>
input.value
'Test123'
input
#<Input: located: True; {'name': 'title', 'tag_name': 'input'}>
input.value = 'Test456'
Traceback (most recent call last):
File "", line 1, in
AttributeError: can't set attribute
input.set('Test456') # AttributeError: Element 'Input' has no attribute 'set'
tf = browser.text_field(name='title')
tf
#<TextField: located: False; {'name': 'title', 'tag_name': 'input'}>
tf.value
'Test123'
tf
#<TextField: located: True; {'name': 'title', 'tag_name': 'input'}>
tf.value = 'Test456'
tf.value
'Test456'
tf.set('Test789')
tf.value
'Test789'

@joshmgrant
Copy link
Contributor

Hi @BradVanDuker, thanks or the ticket!

What did you try to set the value of an input element using Nerodia? One suggested approach would be

browser = Browser(browser='chrome')
browser.text_field(id='some_id_or_something').value ='value_to_set'

Let me know if this works or what else you've tried!

@BradVanDuker
Copy link
Author

First time using bug report on github and the issue was submitted without details (oops!). Initial post edited with more description and console input/output.

@BradVanDuker
Copy link
Author

I forgot to include in the colsole that Input elements don't have a set function

input.set('Test246') # AttributeError: Element 'Input' has no attribute 'set'

@lmtierney
Copy link
Collaborator

@BradVanDuker is there a specific reason you're using 0.11.0 still? There have been vast improvements and bug fixes since then, can you upgrade and try again?

@BradVanDuker
Copy link
Author

After upgrading to the latest version things still stand.

@lmtierney
Copy link
Collaborator

@BradVanDuker I'm sorry I didn't notice earlier, but Input isn't meant to be used directly but rather as the type of input. In most cases, you would use text_field. Other possible valid types could be:

  • button
  • checkbox
  • radio
  • file_field

If you'd prefer to use Input, you can have nerodia convert it for you by to_subtype.

I've verified everything is working fine with a basic example using text_field (as do the CI tests), if you're still having problems after using the specific type of input please let me know.

@BradVanDuker
Copy link
Author

The website I'm testing uses input fields but often doesn't define the type attribute. There's also a lot of div's being used as buttons and inputs. Trying to get a handle on a field via browser.element() or browser.input() works, but using browser.text_field() does not (because there's no explicit tag_type of text_field).

It just seemed a bit odd since value is an attribute of something called Input but you can't really set an Input's vale.

The to_subtype method looks like it will be handy. Thank you very much for pointing that out.

@titusfortner
Copy link
Member

titusfortner commented Mar 18, 2019

@lmtierney if type isn't otherwise specified, it should be treating the input element as a text field.

@lmtierney
Copy link
Collaborator

lmtierney commented Mar 18, 2019

@titusfortner it has the same behavior in Watir. Maybe we need to raise this in Watir as well.

irb(main):001:0> require "watir"
=> true
irb(main):002:0> b = Watir::Browser.new(:firefox)
/Users/lucast/.rbenv/versions/2.4.5/lib/ruby/gems/2.4.0/gems/selenium-webdriver-3.141.0/lib/selenium/webdriver/common/platform.rb:145: warning: Insecure world writable dir /Users/lucast/workspace in PATH, mode 040777
=> #<Watir::Browser:0x..fb1be450570a8e8f6 url="about:blank" title="">
irb(main):003:0> b.goto('www.google.com')
=> "http://www.google.com"
irb(main):004:0> input = b.input(name: 'q')
=> #<Watir::Input: located: false; {:name=>"q", :tag_name=>"input"}>
irb(main):005:0> input.value = 'foo'
NoMethodError: undefined method `value=' for #<Watir::Input: located: true; {:name=>"q", :tag_name=>"input"}>
Did you mean?  value
	from /Users/lucast/.rbenv/versions/2.4.5/lib/ruby/gems/2.4.0/gems/watir-6.16.5/lib/watir/elements/element.rb:844:in `method_missing'
	from (irb):5
	from /Users/lucast/.rbenv/versions/2.4.5/bin/irb:11:in `<main>'
irb(main):006:0> input.set('foo')
NoMethodError: undefined method `set' for #<Watir::Input: located: true; {:name=>"q", :tag_name=>"input"}>
Did you mean?  step
	from /Users/lucast/.rbenv/versions/2.4.5/lib/ruby/gems/2.4.0/gems/watir-6.16.5/lib/watir/elements/element.rb:844:in `method_missing'
	from (irb):6
	from /Users/lucast/.rbenv/versions/2.4.5/bin/irb:11:in `<main>'
irb(main):007:0> 

@titusfortner
Copy link
Member

titusfortner commented Mar 18, 2019

@lmtierney In Watir it should be: input.set 'foo'

@titusfortner
Copy link
Member

Sorry, I didn't read your whole post before replying...

The right answer is that using #text_field should work for anything not defined as NON_TEXT_TYPES: https://github.com/watir/watir/blob/e2905f73c822c5f0a88dfd9e1753d6efd94011dd/lib/watir/elements/text_field.rb#L5

For instance this spec:
https://github.com/watir/watir/blob/master/spec/watirspec/elements/text_field_spec.rb#L60-L62

So in Watir this should work for an input without a type specified:

browser.text_field(id: 'no_type_specified').set 'foo'

@lmtierney
Copy link
Collaborator

lmtierney commented Mar 19, 2019

Nerodia equivalents of the links @titusfortner provided:

NON_TEXT_TYPES = ['file', 'radio', 'checkbox', 'submit', 'reset', 'image', 'button', 'hidden',
'range', 'color', 'date', 'datetime-local']

def test_returns_true_if_the_element_exists_no_type_attribute(self, browser):
assert browser.text_field(id='new_user_first_name').exists is True

@BradVanDuker
Copy link
Author

W3 standard says , "The missing value default is the Text state."

if the Input element is not really meant to be used directly, perhaps browser.Input() should return a text field by default.

@titusfortner
Copy link
Member

Right, if it doesn't have a type specified, then it is displayed in the browser as a text field, so you should use the #text_field method.

There are implementation reasons that something might be an Input class instance and not be a text field.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants