I use:
self.txtLogin_element.when_present.set(email)
But when it executes I get a warning:
*** You are calling a method named set at C:/login_page.rb:12:in `specify_email'.
*** This method does not exist in page-object so it is being passed to the driver.
*** This feature will be removed in the near future.
How to specify a new variant with when_present
Variants:
self.txtLogin_element.when_present = email
self.txtLogin.when_present.set(email)
do not work.
Assuming that txtLogin_element is a text field (PageObject::Elements::TextField), there is no set method. The Page-Object gem sets text fields via the value= method instead. Therefore, to remove the warning, use:
self.txtLogin_element.when_present.value = email
If you have made the switch to Page-Object v2.0 and therefore Watir v6.0, when_present is no longer needed. Watir now waits for elements to be present before interacting with them. You can now simply do:
self.txtLogin_element.value = email
Which ultimately means that you can just use the methods generated by the accessor:
self.txtLogin = email
Related
I am using Capybara and getting errors from the finders 'find_field' & 'has_selector'.
I have tried using them like this:
page = visit "http://www.my-url-here.com"
next if page.has_selector?('#divOutStock')
page.find_field('#txtQty').set('9999')
has_selector returns the error: "NoMethodError: undefined method `has_selector?' for {"status"=>"success"}:Hash"
find_field cannot find the field. (It is present on the page and is not a hidden field.)
I have also tried using fill_in to set the field value, that doesn't work either.
How can I get this to work with Capybara?
You have a couple of issues in your code
page is just an alias for Capybara.current_session. If you assign to it you're creating a local variable and it's no longer a session
find_field takes a locator - http://www.rubydoc.info/gems/capybara/Capybara/Node/Finders#find_field-instance_method - which will be matched against the id, name, or label text. It does not take a CSS selector
Your code should be
page.visit "http://www.my-url-here.com"
next if page.has_selector?('#divOutStock')
page.find_field('txtQty').set('9999')
and you could rewrite the last line as
page.fill_in('txtQty', with: '9999')
Also you should note that (if using a JS capable driver) has_selector? will wait up to Capybara.default_max_wait_time for the #divOutStock to appear. If it's not usually going to be there and you want to speed things up a bit you could do something like
page.visit "http://www.my-url-here.com"
page.assert_text('Something always on page once loaded') #ensure/wait until page is loaded
next if page.has_selector?('#divOutStock', wait: 0) # check for existence and don't retry
page.fill_in('txtQty', with: '9999')
I inherited a test automation suite and while modifying it I am trying to write a function to test similar links which are present in the same web page but in different divs and the tag ids are dynamic.
I have a function defined below which accepts an HTML element and sends an action to the element
def element_do(html_element, html_element_type, html_element_value, action)
#browser.send(html_element.to_sym,html_element_type.to_sym ,html_element_value).send(action)
end
I have a method defined as somemethod and I am trying to call the method in a particular div using the some_element#{i} as below
def multiple_accounts
#num_accts.each do |i|
p "validating for account #{i}"
#page.element_do(:div,:id,"some_element#{i}",somemethod)
end
The issue I am facing is that on second iteration the action parameter is passed as null instead of the somemethod. I am new to ruby automation and I am not sure what exactly is happening. Any help is appreciated
Additional details - based on the questions
1) #num_accts is an array which is got by scanning the text of the webpage and contains account numbers (eg: [56544, 87990])
2) This forms a part of the id for the divs as in "acct#56544". So I am passing the array elements from num_accts to "acct#{i}" referred as 'some_element'
3) 'Somemethod' is a method defined to click on a particular link in the div and verifies a text to confirm that the link redirects to the correct page. The some method works fine when there is only one div.
It is not evident from the question, but my suspicion is that you try to pass the name of the method (which returns null), but instead you call the method. I think your call should be:
#page.element_do(:div,:id,"some_element#{i}",'somemethod')
I could be missing something obvious, but I can't seem to figure out how to update an existing subscriber name in a CreateSend client list using Ruby.
All list details are correct, here's what I have (subscriber already exists in the list):
#subscriber = CreateSend::Subscriber.get(
{:api_key => ENV['CM_API_KEY']}, ENV['CM_LIST_ID'], "me#me.com"
)
According to the tests the update() method should have 4 params:
#subscriber.update("me#me.com", "Name of Person", [], true)
Calling this results in an ArgumentError error: wrong number of arguments (4 for 1).
So, I try calling update by passing in a hash of the updated attributes:
#subscriber.update({"Name" => "New Name"})
No errors occur and the returned #subscriber object contains all the updated fields until you reload it from the API - it's back to the original state.
Reference to the test code:
https://github.com/campaignmonitor/createsend-ruby/blob/master/test/subscriber_test.rb#L51
I've found the answer to this if anyone else experiences the same issue.
CreateSend::Subscriber.get returns an instance of the Hashie class, where the update methods expects one parameter containing a hash. This does not actually update the subscriber details, but only the attributes of the local Hashie instance variable.
CreateSend::Subscriber.new will return an instance of the Subscriber class where the update method expects 4 parameters. Calling the update method in this instance will actually perform the update correctly.
Imagine i have a image like:
the_image = #browser.image(:id, 'image01')
The way to get the value of its class could be:
image_status = the_image.attribute_value('class')
Ok. I'm using page_object gem and lets suppose i have the image as element, like:
image(:the_image, :id => 'image01')
To get the attribute_value i can use:
image_status = the_image_element.attribute_value('class')
...but i get a DEPRECATION WARNING:
*** DEPRECATION WARNING
*** You are calling a method named attribute_value at page.rb:68:in `get_status'.
*** This method does not exist in page-object so it is being passed to the driver.
*** This feature will be removed in the near future.
How can i get the class value using the page_object element? Sure the answer is easy but i didn't found it. Can you please tell me the way?
Thank you in advance!
If you are using the latest versions of Page-Object and Watir (v2.2.1 and v6.7.3 respectively), the attribute_value will no longer give a deprecation warning. Both #attribute and #attribute_value are supported.
For older version of Page-Object, you need to use the #attribute method:
image_status = the_image_element.attribute('class')
I'm automating a site that has a page with a list of options selected by a radio button. When selecting one of the radios, a text field and a select list are presented.
I created a file (test_contracting.rb) that is the one through which I execute the test (ruby test_contracting.rb) and some other classes to represent my page.
On my class ContractPage, I have the following element declaration:
checkbox(:option_sub_domain, :id => "option_sub_domain")
text_field(:domain, :id => "domain_text")
select_list(:tld, :id => "domain_tld")
I've created in the ContractPage a method that sets the configuration of the domain like this:
def configure_domain(config={})
check_option_sub_domain
domain = config[:domain]
tld = config[:tld]
end
When I call the method configure_domain from the test_contracting.rb, it selects the radio button, but it doesn't fill the field with the values. The params are getting into the method correctly. I've checked it using "puts". Even if I change the params to a general string like "bla" it doesnt work. The annoying point is that if on test_contracting.rb I call the exact same components, it works.
my_page_instance = ContractPage.new(browser)
my_page_instance.domain = "bla"
my_page_instance.tld = ".com"
What I found to work was to in the configure_domain method, implement the following:
domain_element.value = config[:domain]
tld_element.send_keys config[:locaweb_domain]
Then it worked.
The documentation for the PageObjects module that I'm using as reference can be found here: http://rubydoc.info/github/cheezy/page-object/master/PageObject/Accessors#select_list-instance_method
Do you guys have any explation on why the method auto generated by the pageobject to set the value of the object didnt work in this scope/context ?
By the way, a friend tried the same thing with Java and it failed as well.
In ruby all equals methods (methods that end with the = sign) need to have a receiver. Let me show you some code that will demonstrate why. Here is the code that sets a local variable to a value:
domain = "blah"
and here is the code that calls the domain= method:
domain = "blah"
In order for ruby to know that you are calling a method instead of setting a local variable you need to add a receiver. Simply change your method above to this and it will work:
def configure_domain(config={})
check_option_sub_domain
self.domain = config[:domain]
self.tld = config[:tld]
end
I'm pretty new to this world of Selenium and page objects but maybe one of my very recent discoveries might help you.
I found that that assignment methods for the select_list fields only worked for me once I started using "self" in front. This is what I have used to access it within my page object code. e.g., self.my_select_list="my select list value"
Another note - The send_keys workaround you mention is clever and might do the trick for a number of uses, but in my case the select list values are variable and may have several options starting with the same letter.
I hope something in here is useful to you.
UPDATE (Jan 3/12)
On diving further into the actual Ruby code for the page object I discovered that the select_list set is also using send_keys, so in actuality I still have the same limitation here as the one I noted using the send_keys workaround directly. sigh So much to learn, so little time!