I am trying to programmatically submit text into a text field using watir. I'm using Stack Overflow as a test site for the script.
I was able to reference the search field (name='q') but the submit button doesn't have an id or name attribute. So how do you reference the submit button programmatically and click it?
This is the code I have so far:
require 'watir'
require 'pry'
browser = Watir::Browser.new :chrome, headless: true
browser.goto 'https://www.stackoverflow.com'
browser.text_field(:name, "q").set('user:963076') #the search bar name='q'
browser.button(#how do I reference the submit button?, '').click
browser.screenshot.save 'screenafter.png' #the screenshot is so that I know what happened after clicking
browser.close
browser.quit
A direct answer to the question is good, but an explanation about how to find solutions to problems like this on your own is better and very much appreciated.
You have to click this button
<button type="submit" aria-label="Search..." class="s-btn s-btn__primary btn-topbar-primary js-search-submit"><svg aria-hidden="true" class="svg-icon mx0 iconSearch" width="18" height="18" viewBox="0 0 18 18"><path d="M12.86 11.32L18 16.5 16.5 18l-5.18-5.14v-.35a7 7 0 1 1 1.19-1.19h.35zM7 12A5 5 0 1 0 7 2a5 5 0 0 0 0 10z"></path></svg></button>
The button has the type attribute with the value of submit so we can use that to locate that button, here is the code
browser.goto 'https://www.stackoverflow.com'
browser.text_field(name: "q").set('user:963076')
browser.button(type: 'submit').click
Related
I have a program where I'm going through tabs by clicking input submit buttons by pressing next or previous. My problem is when I click next it go to the next page and I click to reload the page up in the browser box it it basically go the the next page without me pressing next when I just want to reload the page here is my code for my page action for Next.
app_xval = session("app_xval")
if app_xval="X" then
upl.upload
upl.MaxFileSize = 50000000
page_action = upl.form("btnAction")
has_setup = upl.form("has_setup")
end if
if page_action = "Next" then
app_pg = app_pg + 1
session("app_pg") = app_pg
end if
<input type="submit" class="btn btn-sm btn-primary me-2" name="btnAction" value="Next">
In my test, I am attempting to hit etsy.com, do a search, click on a result, and add the item to my cart. I'm able to do everything up until the point where I attempt to click on the 'add to cart' button. The code below actually works in the IRB so I know my locator is solid, but when I run the test I get an element is unclickable at point error
C:/Ruby24-x64/lib/ruby/gems/2.4.0/gems/selenium-webdriver-3.6.0/lib/selenium/webdriver/remote/response.rb:71:in 'assert_ok': unknown error: Element is not clickable at point (930, 586) (Selenium::WebDriver::Error::UnknownError)
(Session info: chrome=61.0.3163.100)
Here's my test
require 'watir'
# test that a user can search for and add an item to shopping cart
b = Watir::Browser.new :chrome
begin
b.goto "http://etsy.com"
b.text_field(:id => 'search-query').set 'bacon is my spirit animal coaster'
b.button(:value => 'Search').present?
b.button(:value => 'Search').click
b.p(:text => /Bacon Spirit Animal Coaster/).click
b.select_list(:id => 'inventory-variation-select-0').option(:text => 'Single ($8.00)').select
b.button(:text => /Add to cart/).click
if b.text.include?("item in your cart")
puts "Test passed!"
else
puts "Test failed!"
end
ensure
b.close
end
And here is the page HTML for the button.
<button class="btn-transaction" type="submit">
<div class="btn-text">Add to cart</div>
<div class="ui-toolkit">
<div class="btn-spinner spinner spinner-small display-none"></div>
</div>
</button>
Depending on the browser width (and likely other factors), there may be dialogs floating over the add to cart button. For example, when the test failed for me, there was a get started dialog on top of the button. Chrome attempts to click by a location. If another element is on top of your element at that location, Chrome will throw the exception.
The easiest solution is to bypass Chrome's check by directly triggering the click event:
# Watir > 6.8.0:
b.button(:text => /Add to cart/).click! # note the exclamation mark
# Watir < 6.8.0:
b.button(:text => /Add to cart/).fire_event(:onclick)
Other solutions that may conditionally work:
Maximize the browser before clicking the button - browser.window.maximize. This can move the floating element away from the button.
Close the floating dialog.
i m trying to set the checkbox on a radio control with the .set? option. it returns false but I'm unable to set the checkbox.
<div class="">
<input name="radiostorage" id="zrs" value="2" type="radio">
<label for="zrs">Zone-redundant storage (ZRS)</label>
</div>
have tried with label(for: 'zrs').set .click .parent.click .parent.set, also directly trying to click on the input , but nothing happens, any clue on that
TIA
Given the way that the radio button is implemented, it will not be considered visible. You will get an exception trying to set it directly:
browser.radio(id: 'zrs').set
#=> element located, but timed out after 2 seconds, waiting for #<Watir::Radio: located: true; {:id=>"zrs", :tag_name=>"input", :type=>"radio"}> to be present (Watir::Exception::UnknownObjectException)
Instead of setting it directly, you can click its associated label, which is what an actual user would do:
browser = Watir::Browser.new
browser.goto('https://pricing-calculator.bluekiri.cloud/')
p browser.radio(id: 'zrs').set?
#=> false
browser.label(for: 'zrs').click
p browser.radio(id: 'zrs').set?
#=> true
How about
radio = browser.radio(id: 'zrs')
radio.set? #=> false
radio.set
radio.set? #=> true
See http://www.rubydoc.info/gems/watir-webdriver/Watir/Radio
I have a span:
<span class="ToolbarLinkButton" id="ComparisonReports" onclick="function_which_shows_dropdown_menu">
When I click on it I get drop down menu:
<div id="divPopupTemplateComparisonReports">
<div class="ToolbarButtonMenu">
<div class="ToolbarLinkButton" id="ComparisonReportsView" onclick="some_functions">
But when I try to click on element (id="ComparisonReportsView"), it says that: "Selenium::WebDriver::Error::ElementNotVisibleError: Cannot click on element"
on(Main) do |page|
page.spnComprReptVer_element.fire_event ("onclick")
page.divComprReptView_element.click
sleep 2
end
And when via fire_event it says that step passed but nothing was executed (no menu item clicked).
on(Main) do |page|
page.spnComprReptVer_element.fire_event ("onclick")
page.divComprReptView_element.fire_event ("onclick")
sleep 2
end
How I can click on it somehow other way, or what I can use?
I do not know your definition for divComprReptView_element but I assume it has #when_present just use it and give it a block to execute click(e.g. page.divComprReptView_element.when_present.click).
My page contains two divs at the top (a header and another section) that are fixed while the rest of the page can be scrolled. I need to hover over a link element and then click on a button that appears when hovering over the link. Since I am using the page-object gem I tried to use scroll_into_view. However the link still remains behind the fixed divs. This prevents the button from showing. Is there anything that can be done to force it into view? Links at the top and bottom of the scrollable area of the page work fine but items in the middle of the page have issues as they appear behind the fixed divs when scrolled. I am using ruby+watir-webdriver with page-object gem.
Unfortunately I can't post the site.
My code looks something like this:
class MyPage
div(:items, :class => 'product_items')
def index_for(product)
index = items_elements.find_index{|x| x.h4_element.text == product}
index
end
def add_product(product)
index = index_for(product)
product = items_elements[index.to_i]
product.link_element(:class => 'product_more_info').when_present.scroll_into_view
product.link_element(:class => 'product_more_info').hover
product.button_element(:class => 'product_info_button').when_present.click
end
end
The links in the middle of the page remain behind the fixed divs. When it hovers it actually triggers a nav dropdown that is in the header since the link is directly behind it. Seems to work for 70% of the links. The 30% in the middle are the issue right now.
I think I have reproduced your problem with the following page. When the div element to hover on is scrolled into view, it appears below the menu. Hovering does not cause the onmouseover to trigger.
<html>
<body>
<div style="position:fixed; left:0; top:0; z-index=99999; border:2px solid red; width:100%">menu</div>
<div class="spacer" style="height:2000px"></div>
<div id="hoverable" onmouseover="document.getElementById('target').style.display = '';">to hover</div>
<button id="target" style="display:none;">the button</button>
<div class="spacer" style="height:2000px"></div>
</body>
</html>
One solution that works (at least for this example page), was to try hovering over the element. If the button did not appear, assume that the menu is in the way, scroll back up the page a bit and try again. Assuming the above page, this could be done with the page object:
class MyPage
include PageObject
div(:hoverable, :id => "hoverable")
button(:target, :id => "target")
def hover()
# Try to hover over the element
hoverable_element.when_present.hover
# If the button element does not appear, the menu must be in the way.
# Scroll back up 100 px so that the div appears below the menu and try again.
unless target_element.visible?
execute_script('window.scrollBy(0,-100);')
hoverable_element.hover
end
# Check that the button appears as expected
p target_element.visible?
#=> true
end
end
Applying the same idea to your page object, the add_product method would become:
def add_product(product)
index = index_for(product)
product = items_elements[index.to_i]
product.link_element(:class => 'product_more_info').hover
unless button_element(:class => 'product_info_button').visible?
execute_script('window.scrollBy(0,-100);')
product.link_element(:class => 'product_more_info').hover
end
product.button_element(:class => 'product_info_button').click
end