I'm new to page-object and selenium, but so far it's all been going ok. The last elements I'm testing for this page are social media links.
To check that the links are correct i usually click them and then use selenium's driver.current_url to check that the url of the window is what we'd expect for that link, but these social media buttons are opening links in a new window (this is just to their static facebook page rather than a login etc) which causes the test to fail
is there a way of either:
1-forcing the link to open in the current window, or
2-extracting the target url from the link_element?
this is what the tests look like atm:
def test_facebook_button
assert #testpage.facebook_icon?, 'Facebook button not found'
#testpage.facebook_icon_link
sleep 5
assert #browser.current_url == '<facebookurlforsite>', 'Facebook link does not open expected URL'
end
if not i'm guessing i'd just use the actual selenium methods as some sort of exception to manually grab the properties of the link, i'd rather not some elements be in the page model and some out in the test itself but i can see how it's probably necessary
If you are just checking that the link navigates to the right URL, checking the link's href attribute will be the quickest. The PageObject::Elements::Link elements have an href method for this.
Assuming that facebook_icon_link is your link defined by an accessor method, you would call:
facebook_icon_link_element.href
In other words, the assertion could be written as:
assert facebook_icon_link_element.href == '<facebookurlforsite>'
Related
I'm running automated testing in Ruby.
I'm trying to write a script that finds id with display:none (visible only in mobile form), and clicks it.
Here is my code:
def open_menu
page.find[:css, "a[id='mobile-nav-link']", visible: false].click
end
It gives me an error:
Selenium::WebDriver::Error::InvalidSelectorError:
invalid selector: No selector specified
A quick search reveals similar code using round brackets, not square. I.e.:
def open_menu
page.find(:css, "a[id='mobile-nav-link']", visible: false).click
end
Selenium only interacts with elements the way a user would.
If the link is only visible in mobile, I would suggest one of the following.
View the page via the mobile URL.
It's possible that you may be able to use Ruby's javascript execute to either update the control to be visible, or set the value that indicates you are viewing the page via a mobile device.
Updating the control to be visible
This link discusses how to set an element to visible using javascript execute: Selenium Webdriver - click on hidden elements
This link discusses how to use ruby's javascript execute: How to execute Javascript in Ruby written Webdriver test?
Put the two together, and you get something like this?
def open_menu
elem = page.find[:css, "a[id='mobile-nav-link']", visible: false]
js = "arguments[0].style.height='auto' arguments[0].style.visibility='visible';"
driver.execute_script(js , elem)
page.find[:css, "a[id='mobile-nav-link']", visible: true].click
end
I'm not entirely familiar with Ruby syntax, so I make no guarantees it will work copy/paste.
I am trying to automate tests in Ruby using the latest Watir-Webdriver 0.9.1, Selenium-Webdriver 2.53.0 and Chrome extension 2.21. However the website that I am testing has static headers at the top or sometimes static footers at the bottom. Hence since Watir auto-scrolls an element into view before clicking, the elements get hidden under the static header or the static footer. I do not want to set desired_capabitlites (ElementScrollBehavior) to 1 or 0 as the websites I am testing can have both - static header or static footer or both.
Hence the question are:
1) Why does Watir throw an exception Element not clickable even when the element is visible and present? See ruby code ( I have picked a random company website for an example) and the results below.
2) How can I resolve this without resorting to ElementScrollBehaviour?
Ruby code:
require 'watir-webdriver'
browser = Watir::Browser.new :chrome
begin
# Step 1
browser.goto "shop.coles.com.au/online/mobile/national"
# Step 2 - click on 'Full Website' link at the bottom
link = browser.link(text: "Full website")
#check if link exists, present and visible?
puts link.exists?
puts link.present?
puts link.visible?
#click on link
link.click
rescue => e
puts e.inspect
ensure
sleep 5
end
puts browser.url
browser.close
Result:
$ ruby link_not_clickable.rb
true
true
true
Selenium::WebDriver::Error::UnknownError: unknown error: Element is not clickable at point (460, 1295). Other element would receive the click: div class="shoppingFooter"...div
(Session info: chrome=50.0.2661.75)
(Driver info: chromedriver=2.21.371459 (36d3d07f660ff2bc1bf28a75d1cdabed0983e7c4),platform=Mac OS X 10.10.5 x86_64)>
http://shop.coles.com.au/online/mobile/national
thanks!
You can do a click at any element without getting it visible. Check this out:
link.fire_event('click')
BUT It is very very very not good decision as far as it will click the element even if it is not actually visible or in case when it is just impossible to click it (because of broken sticky footer for example).
That's why much better to wait the fooler, scroll the page and then click like:
browser.div(id: "footerMessageArea").wait_until_present
browser.execute_script("window.scrollTo(0, document.body.scrollHeight);")
link.click
The sticky footer is blocking webdriver from performing the click, hence the message that says 'other element would receive the click'.
There are several different ways you can get around this.
Scroll down to the bottom of the page before the click
Hide/Delete the sticky footer before any/all link clicks
Focus on an element below the element you want to click before you perform the click
I Guess your element is visible in the screen.
Before clicking on the element first you have to scroll the webpage so that element is visible then perform the click. Hope it should work.
I had similar issue,
I just used following javascript code with watir:
link = browser.link(text: "Full website")
#browser.execute_script("arguments[0].focus(); arguments[0].click();", link)
Sometimes I have to use .click! which i believe is the fire_event equivalent. Basically something is layered weird, and you just have to go around the front end mess.
I am using ruby and capybara(which leverages selenium) to automate walking through a website. After navigating to a new page I verify that the new page URL is what i'm expecting. My issue comes when I walk through an order funnel that is a single page but loads different views.
Some code...
I create my session instance then have additional code opening the browser and walking to a certain point in the website that I wont include
$session = Capybara::Session.new(:selenium)
My line for checking the browser URL without search params ie: everything after '?'
if url == $session.current_url.to_s.split("?")[0]
urlCorrect = true
end
This code works fine when my URL is
https://www.homepage.com
Then I click on a link that takes me to my order funnel ... https://www.homepage.com/order#/orderpage1?option1=something&option2=somethingelse
My function still matches the expected URL. But the issue comes when I move to the second page of the order funnel :
https://www.homepage.com/order#/orderpage2?option1=something&option2=somethingelse
My capybara code to get current url still returns the URL from orderpage1. Im guessing its because there is no postback when moving from orderpage1 to orderpage2 but i dont know how to force a postback or tell capybara to re-grab the url
Any advice will be appreciated.
Thanks
Quick Edit: I forgot to mention this behavior is only in IE. Chrome and Firefox both work correctly with the exact same code
Capybara grabs the current_url by querying the browser - it doesn't cache it. The issue you're probably running into is that clicking the link to move to the next page doesn't wait for the page change to happen, so if you call current_url before the page load has happened you'll still get the original url. There are two solutions for that - 1. use capybara to look for content that doesn't appear until the new page is loaded ( have_content ), 2. use the has_current_path? method which will wait/retry for a period of time until the current_path/url match
$session.has_current_path?('expected path')
There are options if you want to match against the full url, and you can use a regex to match as well - http://www.rubydoc.info/gems/capybara/Capybara/SessionMatchers#has_current_path%3F-instance_method
Thanks to Tom Walpole for finding the bug report for this issue. This link sums up the root of the issue and provides a few workarounds if anyone else is encountering this issue.
https://github.com/angular/protractor/issues/132
I'm using watir-webdriver with the page-object gem to drive cucumber tests for a single web page app built in angular js.
The site uses a multiple stage registration process, filling a series of details each time then clicking a 'next' button. (which is enabled when all details are completed for that page)
The issue occurs when I'm attempting to reuse the following step definition:
And(/^I click next$/) do
#registration = RegistrationPage.new(#browser)
#registration.click_next
end
Which calls the page-object:
class RegistrationPage
include PageObject
button(:next, :value => "Next")
def click_next
#browser.wait_while { next_element.disabled? }
next_element.click
end
end
For the first section, the Next button is found correctly, however on the second call to the step definition, the button cannot be found, despite the button being verifiably enabled and otherwise identical.
I see that you've answered your question but in case it helps to explain it to anyone else:
The issue is likely that to watir it isn't the same next button on each page and all of the next buttons are in scope all of the time. Therefore to click the correct one you would have to use the index property of the button you want i.e. index: 1 for the second page and index 2 for the the button on the third page.
I clicked on a button on some page which redirects me to some other page.but between these pages there is one page which comes only for 1 or 2 seconds. I have to verify that page.I am using selenium.
Any suggestions?
What you could do here, is do a simple waitForElement subroutine.
Ideally, when your test framework cannot find an element to operate with, it will fail.
So we can assume, that when your test gets past waitForElement(theInterimElement) then your interim element has appeared, and we can continue.
Check the url of the page is the url of the desired page and wait while this is not true.
while (!webDriver.Url.Contains(desiredUrl.ToString()))
Thread.Sleep(50);