Is there a difference between "is visible" and "click element" in Robot Framework/Selenium? - selenium

These two lines don't work as expected:
wait until element is visible ${my xpath}
SeleniumLibrary.click element ${my xpath}
Approximately half of the time the second line fails. I am not in front of my computer now but it either fails with stale element or couldn't find element with id....
If I add a sleep 3 or so inbetween the lines the second line never fails.
These two lines work frequently but they also fail frequently. Is there a difference in how RF detects that something is visible and how Selenium sends a click to the same element?

You can include a custom timeout in the first keyword instead of using sleep.
Wait Until Element Is Visible ${my xpath} 3 seconds
Click Element ${my xpath}

To answer your question in short no there is no difference between how RF detects that something is visible and how selenium sends a click to that same element. I looked at the source code for Selenium and both functions use the same locator argument.
#keyword
def click_element(self, locator, modifier=False, action_chain=False):
and
#keyword
def wait_until_element_is_visible(self, locator, timeout=None, error=None):
A keyword instead I would suggest is
wait until page contains element ${my xpath}
This allows for the web page to be fully loaded before looking for the element.

Related

WebDriverWait.until.expected_conditions.presence_of_element_located not waiting for reloaded DOM

I have an app with 2 buttons. Button A takes the app to a new page with no buttons, then returns to the page with 2 buttons. My automated test is meant to click on Button A, wait while the app heads to the new pages and returns, then click on Button B.
The code:
el05a = WebDriverWait(driver, 120).until(
expected_conditions.presence_of_element_located((By.ID, "id_of_button_a"))
)
el05a.click()
el05b = WebDriverWait(driver, 120).until(
expected_conditions.presence_of_element_located((By.ID, "id_of_button_b"))
)
el05b.click()
However, I receive a StaleElementReferenceException about button B not being in DOM anymore.
Obviously, button B is not gonna be in the DOM while the app is at the new page, but why does my code not know to wait until the presence of button B is located? I thought presence_of_element_located means the code would be on hold until the element is located.
I know this could "technically" be patched with a time.sleep module but I'm trying to avoid that.
As per your query it seems likes as your checking presence_of_element_located and which only check for it presence and not the visibility of the element.
Try replacing the presence_of_element_located with visibility_of_element_located.
There is difference between visibility_of_element_located and presence_of_element_located.
1) visibility_of_element_located
Checking that an element is present on the DOM of a page and visible. Basically it tests if the element we are looking for is present as well as visible on the page.
2) presence_of_element_located
Checking that an element is present on the DOM of a page. Basically it tests if the element we are looking for is present somewhere on the page.
Code:
el05a = WebDriverWait(driver, 120).until(
expected_conditions. visibility_of_element_located((By.ID, "id_of_button_a"))
)
el05a.click()
el05b = WebDriverWait(driver, 120).until(
expected_conditions. visibility_of_element_located((By.ID, "id_of_button_b"))
)
el05b.click()
visibility_of_element_located: Returns the WebElement once it is located and visible.
An expectation for checking that an element is present on the DOM of a page and visible. Visibility means that the element is not only displayed but also has a height and width that is greater than 0.
presence_of_element_located: Returns the WebElement if element is present on DOM and not even visible.
An expectation for checking that an element is present on the DOM of a page. This does not necessarily mean that the element is visible.
Please change it from
expected_conditions.presence_of_element_located((By.ID, "id_of_button_a"))
to
expected_conditions.visibility_of_element_located((By.ID, "id_of_button_a"))

Waiting function for CSS element in Capybara

There are waiting and non-waiting functions in Capybara. I am trying to use the first as much as possible.
Is there a way to use find (or one of its derivatives) to look for a CSS element that appears asynchronously?
Unfortunately, function page.has_css? is a non-waiting function.
Your claim that page.has_css? is a non-waiting function is not correct. page.has_css? will wait up to Capybara.default_max_wait_time seconds for an element to appear on the page and return true or false based on whether or not the element is on the page within that time. Therefore, given Capybara.default_max_wait_time = 5
if page.has_css?("div#my_div")
puts "on page"
else
puts "not on page"
end
will wait for up to 5 seconds. As soon as a div with id of "my_div" is visible on the page it will print "on page". If a matching div doesn't become visible within 5 seconds it will print "not on page". If you want it to wait longer for a specific call you can override default_max_wait_time by passing the :wait option
if page.has_css?("div#my_div", wait: 10) # will wait up to 10 seconds
...
If rather than wanting a boolean response you want to ensure the element exists you can do any of
page.assert_selector(:css, 'div#my_div') # :css is the default so can usually be omitted
page.assert_css('div#my_div') # minitest
expect(page).to have_css('div#my_div') # RSpec
which will wait for the element to appear as previously, but raise an exception rather than returning false if the element does not appear
If you need the actual element you can use find which will also wait. So
el = page.find(:css, 'div#my_div') # :css is the default and can usually be omitted
will wait for the element to appear and return the element when found. If the element is not found within default_max_wait_time seconds it will raise an exception.
Note: Basically, the only non-waiting methods are all and first and even those can be made to wait if you pass in any of the count options (:count, :minimum, :maximum, :between), although the elements returned from them would still be non-reloadable and can therefore have further behavior effects if used for scoping, etc. Even methods like click_link, click_button, etc will wait since they are implemented as find(...).click, etc

Why my Selenium web driver is not clicking on Element identified by id?

My Selenium web driver is not clicking on this tree node. I don't know exactly what we say it tree node or something else so this is image and I highlighted the element.
This right arrow part on which I want to click
And this is my code:
//wait.until(ExpectedConditions.elementToBeClickable(By.id("iconDiv")));
WebElement taskdropElementid = driver.findElement(By.id("iconDiv"));
System.out.println(taskdropElementid.getAttribute("class"));
if(taskdropElementid.getAttribute("class").equals("RightArrow"))
taskdropElementid.click();
Printing statement is giving me output dropdown. I think it should give RightArrow and when I am uncommenting wait part then it is continuously wait for the element to be clickable.
What am I doing wrong?
Printing statement is giving me output dropdown
That means there are multiple elements with the same id iconDiv and unfortunately you're locating other element instead which has class name dropdown.
If you want to locate element with class name RightArrow, You should try using By.cssSelector() to locate it uniquely as below :-
WebElement taskdropElementid = driver.findElement(By.cssSelector("div#iconDiv.RightArrow"));
taskdropElementid.click();

Nightwatch .waitForElementVisible('#primary-btn') warning : WaitForElement found 2 elements

I am using nightwatch with chrome driver for UI-Testing. I have come across an issue when trying to click on 'primary-btn' in the web-page. First the waitForElement returns a warning "Warn: WaitForElement found 2 elements for selector "#primary-btn". Only the first one will be checked" and the subsequent .click('#primary-btn') does not yield the desired result.
I checked the web-page to see if actually there are 2 elements with the name "#primary-btn" using document.getElementById('primary-btn'). However the function listed only 1 element with id 'primary-btn'
I am not sure why this happens. Does nightwatch support wait for animation to finish.
You should try this
document.querySelectorAll("div[id='primary-btn']:nth-child(1)")
In nightwatch :
browser.waitForElementPresent("div[id='primary-btn']:nth-child(1)")
It means that you have 2 elements in you page with an identical id. While the standard impose a unique name, it is not enforced in the browser. You can verify it by executing this command in your browser:
document.querySelectorAll("[id='primary-btn']")
Or:
$x("//*[#id='primary-btn']")
So to get the expected element, you need to extend your selector with another condition. It could be for example:
'#container-id #primary-btn'

Selenium WebDriver access a sub element

I have a div with a unique ID. Under that div are a bunch of span elements that have className=foo. There are several span elements with className=foo but they are unique to each div (if that's clear). So my Selenium code first gets the unique div as a web element then tries to take that element and get by class name the span like so
element = sDriver.findElement(By.id("c_"+cID));
String sTest = element.findElement(By.className("actions")).getText();
On the second line it throws an exception every time
org.openqa.selenium.StaleElementReferenceException: Element not found in the cache - perhaps the page has changed since it was looked up
Command duration or timeout: 22 milliseconds
Do I misunderstand how to get that span from under a unique div?
Nope you'right accessing the span but the problem is that the Dom has changed since StaleReferenceException is about (see StaleReferenceException )
This may be caused because the page isn't loaded completely when the code starts or changes when the code is executed. You can either try to wait a little longer for the element or catch the StaleReferenceException and try again finding the div and the span.
My solution is not fancy but it works like a Swiss watch (in my situation of course). So my code is calling the parent element in a loop looking for different child elements in it. Nothing got changed at all - just simple querying and the exception began to occur. So! I've added the Thread.Sleep(2000) command before every search of parent element and it solver the problem. Not elegant but works every time with minimum code to debug afterwards.