nerodia icon indicating copy to clipboard operation
nerodia copied to clipboard

Can't set value of Input Element

Open BradVanDuker opened this issue 5 years ago • 14 comments

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'

BradVanDuker avatar Mar 18 '19 15:03 BradVanDuker

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!

joshmgrant avatar Mar 18 '19 15:03 joshmgrant

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 avatar Mar 18 '19 16:03 BradVanDuker

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'

BradVanDuker avatar Mar 18 '19 16:03 BradVanDuker

@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?

lmtierney avatar Mar 18 '19 18:03 lmtierney

After upgrading to the latest version things still stand.

BradVanDuker avatar Mar 18 '19 19:03 BradVanDuker

@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.

lmtierney avatar Mar 18 '19 20:03 lmtierney

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.

BradVanDuker avatar Mar 18 '19 21:03 BradVanDuker

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

titusfortner avatar Mar 18 '19 21:03 titusfortner

@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> 

lmtierney avatar Mar 18 '19 21:03 lmtierney

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

titusfortner avatar Mar 18 '19 22:03 titusfortner

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'

titusfortner avatar Mar 19 '19 00:03 titusfortner

Nerodia equivalents of the links @titusfortner provided:

https://github.com/watir/nerodia/blob/024c2150effa12f677e4cd9fc9ef651ac2198616/nerodia/elements/text_field.py#L13-L14

https://github.com/watir/nerodia/blob/117fd1881844867b15625e7214605aa30183636d/tests/browser/elements/text_field_tests.py#L48-L49

lmtierney avatar Mar 19 '19 01:03 lmtierney

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.

BradVanDuker avatar Mar 19 '19 20:03 BradVanDuker

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.

titusfortner avatar Mar 19 '19 23:03 titusfortner