I am trying to write a small Shoes app which contains a button. For example
Shoes.app :title => "Buttons" do
button_next = button "Next"
button_prev = button "Previous"
end
Now, instead of the texts "Next" or "Previous" there should be icons on the buttons: a green arrow, showing to the right for the button_next and a green arrow showing to the left for the button_prev.
Of couse I already have the icons as .jpg-files but I can't figure out how to replace the text with the icons on the buttons.
For now I found out this way:
Shoes.app do
next_image = image "next.jpg", :width => 50, :height => 35
next_image.click do
alert "Hey!"
end
end
It works in the way that I can click the image and a new window, saying "Hey!" appears. But it is not ok, because I miss the typical button-appearance like changing of the color when hovering over it, or the press-down-effect when clicking on it.
So my question is: how can I create a real button in Ruby Shoes and replace the name of the button with an icon? Any ideas?
Related
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 tried xpath and id
getting `until': timed out after 10 seconds (no such element (Selenium::WebDriver::Error::TimeOutError)
I am using rubymine editor.
wait = Selenium::WebDriver::Wait.new(:timeout => 10)
wait.until { #driver.find_element(:xpath => "//*[#id='j_id0:pb:j_id35']") }
#driver.find_element(:xpath => "//*[#id='j_id0:pb:j_id35']").send_keys "test send sms"
Text area element is placed on bottom of the page.Do I need to scroll down the page and click and sendkeys in the text area.
in the below code I am trying to find nearest element to the text box and do scroll down later click on text area and sendkeys.But even it's not working..
#wait = Selenium::WebDriver::Wait.new(:timeout => 10)
#wait.until { #driver.find_element(:name => "j_id0:pb:j_id33") }
#scroll = #driver.find_element(:name => "j_id0:pb:j_id33")
#scroll.location_once_scrolled_into_view
Please help on this..
Thanks!!
I don't have idea on rudy but can help you logically..
1) first scroll the page from your code to the text area.
2) select the text area by id, xpath or etc. driver.findelement(by.id(...)).sendkey(..........);
Thanks Shukla!#sourabh shukla
Mine inside has frame so I need to switch to frame that is why I am not able ciclk that element!!
#driver.switch_to.frame("06618000000Crrp"#this is id);
Then my element found and entered text!!
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
I am testing an webview app containing multiple webviews/pages. To get the webviews I do:
$driver.window_handles
which returns me an array of window indexes of numbers something like ['1', '3', '5', '6', '7', '8']
Now if I want to switch to a specific window which contains text "My TITLE"; I have to iterate through each of the indexes in the array using loop and switch the window to that index and then check if the text is present in that window.
Eg:
$driver.switch_to.window('1') if 'My Title' not found; $driver.switch_to.window('3') and so on until I find the window.
I even tried to look for the title of the window/driver; but for some windows I am getting title as nil so wasn't a best way for me to find out the window.
Is there any other way I can try to get the required window?
You can take the below approach:
#create a array with window_id and its corresponding window page title
wnd_titl = driver.window_handles.map do |w|
driver.switch_to.window(w)
[w,driver.title]
end
#required window
win_id = wnd_titl.find { |e1,e2| e2 == 'My TITLE' }.first
driver.switch_to.window(win_id) #switched to the required window
I'm coding on Tk 8.5.9 from ActiveTcl on Ruby 1.8.7 on a Mac OS X 10.6.
To meet my application requirements I need to make the button widgets as small as the gif image but I am not able to. I have been hours searching and experimenting with negative results.
Greatly thankful in advance for any clues.
Following is the code i am trying to get small buttons from.
require 'tk'
require 'tkextlib/tile'
$up_img = TkPhotoImage.new("file"=>"arrowup-n.gif")
$down_img = TkPhotoImage.new("file"=>"arrowdown-n.gif")
root = TkRoot.new {title "Ek Composer"}
content = Tk::Tile::Frame.new(root).pack
Tk::Tile::Button.new(content) {width 1;image $up_img; command {move_up} }.pack
Tk::Tile::Button.new(content) {width 1;image $down_img;command {move_down}}.pack
def move_up
p "move up"
end
def move_down
p "move down"
end
Tk.mainloop
But the buttons remain too big :(.
It's awkward. The OSX theme really wants to add extra space at either end of the button.
You can try switching to the classic button (in tk itself) but that puts more space vertically and looks a bit less native. Or you can put the image in a label (which you can shrink exactly) and add bindings to it to make it respond to mouse clicks.
I added binding to label. Works fine. Thanks. Follows a code snippet of label with binding as button.
require 'tk'
$resultsVar = TkVariable.new
root = TkRoot.new
root.title = "Window"
$up_img = TkPhotoImage.new("file"=>"arrowup-n.gif")
$down_img = TkPhotoImage.new("file"=>"arrowdown-n.gif")
Lbl = TkLabel.new(root) do
image $up_img
borderwidth 0
font TkFont.new('times 20 bold')
foreground "red"
relief "groove"
pack("side" => "right", "padx"=> "50", "pady"=> "50")
end
Lbl.bind("ButtonPress-1") {
Lbl.configure("image"=>$down_img)
}
Lbl.bind("ButtonRelease-1") {
Lbl.configure("image"=>$up_img)
}
Lbl['textvariable'] = $resultsVar
$resultsVar.value = 'New value to display'
Tk.mainloop