element not visible Selenium capybara - selenium

I am getting below error while executing below capybara command,
The interesting thing is the same XPath is not giving any error in I am expecting that XPath to be present.
But when I am trying to perform click on that XPath, it's throwing below error.
--------------code----------------
Then(/^I click on "([^"])" on left tree child of "([^"])"$/) do |child, parent|
within(:xpath, ".//div/span[#class='folder-nav-tree-fileroom' and text()='DND-IndexTwistyExpClps']/../../../../..", wait:5) do
find(:xpath, ".//span[contains(text(),  '1 IndexTwistyLevel1')]/../../../span[#class='ui-tree-toggler fa fa-fw fa-caret-right']", wait:5).click
end
end
Error : Capybara::ElementNotFound: Unable to find visible xpath "//div[.//span[contains(text(),  '1 IndexTwistyLevel1')]]/span[#class='ui-tree-toggler fa fa-fw fa-caret-right']"

Your code has a number of issues, which indicate it can't actually be working like you claim. If you fix the code and provide the HTML fragment it should be matching against we can narrow done to the issue, but for now the errors are:
Firstly, you have mismatched/non-escaped
's and )s in your XPath expressions (can't have inside a string surrounded bys so it's obvious you haven't copy/pasted your actual code)
Secondly, ::after is not valid XPath - ::after pseudo elements are purely CSS and can't be accessed from XPath, so including that in your selector isn't going to give the expected results. This should result in an invalid selector error being raised by Chrome.
Thirdly, by not starting your selectors with . you're completely defeating the within scoping block - see https://github.com/teamcapybara/capybara#beware-the-xpath--trap
Finally, using visible: false on an element you want to click makes no sense, since you can't click on an element that isn't displayed on the page.
Unfortunately its tough to tell which of these may be causing your actual issue (if any) since the code you have provided isn't valid.

within(:xpath, config['documents_obj']['FRChildTreeXpath'].sub('TEXT', parent), wait:5) do
elem = find(:xpath, config['documents_obj']['childTwistyXpath'].sub('TEXT', child), visible:false, wait:5).native
page.driver.browser.action.click(elem).perform
To avoid the error which iwas gettign what i simply did, is I used capybara action builder,
Take the native element then perform the action.
It worked perfectly in my case.
Reference : https://seleniumhq.github.io/selenium/docs/api/rb/Selenium/WebDriver/ActionBuilder.html

Related

How to implement //*[contains(text(), '"example"')] to construct an Xpath for dynamic contents for Selenium Webdriver:?

I'm working through Selenium Webdriver, and I've come up to the issue of dynamic objects as a DOM ID. One of my instances gets generated as an ID, something like this:
"//*[#id="888itsAnExampleBoi573"]/div[1]/div[2]",
and I need to click on the button in the example item to Make Stuff Happen.
Because I cannot predict what an objectID will be for my dynamic content, however, I would like to be able to do this, instead:
//*[contains(text(), 'example')]/div[1]/div[2].
I've tried to do this, but I'm returned a strange error:
Caused by: org.openqa.selenium.InvalidSelectorException: invalid
selector: Unable to locate an element with the xpath expression
//*[contains(text(), 'example')]/div/div/div[1]/div[3]/div
because of the following error:
SyntaxError: Failed to execute 'evaluate' on 'Document':
The string '//*[contains(text(), 'example')]/div/div/div[1]/div[3]/div'
is not a valid XPath expression.
On a different element that is a hyperlink with text elements, I've been able to use contains(text()) to solve things, so I believe I've formatted this correctly.
I've tried a few different things to solve this issue, but am at somewhat of a loss as to how to solve this. Does anyone have any ideas or resources to point me towards? Or better yet, a solution?
This error message...
Caused by: org.openqa.selenium.InvalidSelectorException: invalid selector: Unable to locate an element with the xpath expression //*[contains(text(), 'example')]/div/div/div[1]/div[3]/div because of the following error: SyntaxError: Failed to execute 'evaluate' on 'Document': The string '//*[contains(text(), 'example')]/div/div/div[1]/div[3]/div' is not a valid XPath expression.
...implies that the Locator Strategy is not a valid XPath expression.
The expressions:
'//*[contains(text(), 'example')]/div/div/div[1]/div[3]/div'
"//*[contains(text(), "example")]/div/div/div[1]/div[3]/div"
Are invalid as '' and "" were present in multiple places within the xpath.
Solution
As an effective alternative dynamic xpath for the following:
"//*[#id="888itsAnExampleBoi573"]/div[1]/div[2]"
will be:
"//*[contains(#id,'itsAnExampleBoi')]/div[1]/div[2]"
It appears that in order to solve this, sometimes you must frame the question. As I had been using a relative XPATH, I had been working under the pretense that the text div itself was where I would be able to access elements that were not the children of my div. They were actually only loosely related!
"//*[contains(text(), 'Flag this')]
//parent::div
//parent::div[contains(#class,'exampleDrop')]
//child::div[contains(#class, 'pointed exampleAction')]"
I ended up installing Chropath and spidering around the DOM, finding the div with the text in it, and using a relative path in this statement. If you're having issues like these, sometimes I would recommend making sure that you're asking the right question.

How to get the text from an element which disappears quickly using protractor

I need to get the text from element P but protractor keeps returning error
Code:
<div class = "ui-growl-message">
<span class = "ui-growl- title">Sucesso</span>
<p>cargo Cadastrado cm sucesso!</p>
</div>
I've tried this way:
const msgValidacao = element(by.css('ui-growl-message')).all(by.tagName('p')).first().getText().then(() => {
expect(msgValidacao).toContain('Cargo cadastrado com sucesso');
});
and the Error is:
Failed: No element found using locator: By(css selector,
ui-growl-message)
The problem is the element is a warning so it quickly disappears from the screen.
In addition to the css correction, you'll also want to employ some sort of wait strategy to anticipate the message and grab the content as close to the moment of the initial rendering as possible. Automation around very short-lived messages can be challenging due to intricate timing factors.
It might be not the real problem why it returns that element is not found. I thing that the selector is not good. If the element disappears quickly as You say sometimes the test will pass and sometimes it will fail. Try another selector and make sure that You have the correct one.
If you want to select first element use get(0) not first()
element(by.css('ui-growl-message')).all(by.tagName('p')).get(0)

How to make geb throw error when element not found instead of returning EmptyNavigator

in my page object I have simple method
def clickSomething(byName) {
$("a.name", text: contains(byName)).click()
}
and during execution it does not find required element and goes further.
it happens because, according to documentation, $() returns EmptyNavigator if element not found.
I want for test to fail with some kind of "ElementNotFoundException" or "NullPointerException" on trying to make click on null element.
I also do not want to add additional checks for returned element (because I would need to add that for every element identification).
Is there an elegant workaround for that ?
e.g. for elements declared within "content" there is performed such a check. But what is the best practice for elements found outside content block ?
The issue that you've encountered which is click() not throwing an error when called on en empty navigator has been fixed recently and will be released in the next version of Geb.
If you need to get an error when a selector results in an empty navigator then you can either:
wrap your selector in a content definition with the required template option set to true which is the default
call verifyNotEmpty() on your navigator

Selenium preceding-sibling::text() not working

I am having issues with selenium using the next xpath "./preceding-sibling::text()"
I don't understand why, my first thought was that IE wasn't supporting that xpath statement but it didnt work on chrome neither.
What I am trying to do is to verify if a radio button have a certain text "near" it. For example if a radio button is like this
<div>
<label> Yes <input name='radioBtn'></input></label>
<label> No <input name='radioBtn'></input></label>
</div>
This is a simplified scenario where I need to check the "yes" radio button, so what I am doing is to search for the radiobutton and check if it preceding-sibling::text(), but selenium is cant find any element. I know the Xpath works because I test it on chrome developer tools and it returns the text "Yes".
I can't do something like 'input[1]' because I can't be sure that the first one will be always that have the Yes text.
Any idea why isn't this working on selenium? and if there is any work around?
I got to a work around but is kind of specific to the problem. But let's answer the questions 1 at the time.
Any idea why isn't this working on selenium?
It's not working because selenium don't support text elements, so even when selenium find the element it cant map it to a selenium object, i didn't see it because my code hided the selenium exception. The Exception throw is the next one:
An unhandled exception of type
'OpenQA.Selenium.InvalidSelectorException' occurred in WebDriver.dll
Additional information: invalid selector: The result of the xpath
expression "./preceding-sibling::text()" is: [object Text]. It should
be an element
Is there any work around?
Yes it is. What I did was to run a java script using the selenium IJavaScriptExecutor. With the script I revised the preceding sibling text and return it as a string so if the text was equal to the thing I was looking for (i.e Yes) trhat means that is the radio button I was looking for.
The code looks is similar to this (it can have some sintax errors since I didn't copied from the source):
string script = "function GetPrecedingText(node){"+
"var result = document.evaluate('./preceding-sibling::text()[1]', node, null, XPathResult.STRING_TYPE, null);"+
"return (result==null) ? '' : result.stringValue.trim();}"+
"return GetPrecedingText(arguments[0])";
string result = ((driver as IJavaScriptExecutor).ExecuteScript(script, SeleniumElement)).toString();
Hope someone can find this useful :) and thanks for all that tried to help me :)

XPath query search

Such structure is given
<div class="user-number">123</div>
<div class="user-state">
<span class="u-state-icon icon icon-1"></span>
<span> User1</span>
</div>
I've tried such (incorrect) xpath for locating User1 by user-number and do not understand where is the problem..
xpath=//*[#class='user-number' and text() = '123']/following-sibling::*[contains(#class,'user-state')]/descendant::*[contains(#text,'User1')]
What is the best way to debug it?
For example, if
xpath=//*[#class='user-number' and text() = '123']/following-sibling::*[contains(#class,'user-state')]
locates some element - how to print out its text property - to check which element is actually located?
Your xpath expression is, surely, incorrect - #text should be replaced with text() (or just .):
//*[#class='user-number' and . = '123']/following-sibling::*[contains(#class,'user-state')]/descendant::*[contains(.,'User1')]
Debugging xpath expressions is usually done using the browser developer tools: in the firebug, or inside a browser console. For instance, in the google-chrome console, you can execute the following:
$x("//*[#class='user-number' and . = '123']/following-sibling::*[contains(#class,'user-state')")
And see if there is a match.
Or, you can also debug it inside your code. For example (using python), find the first div element and print out it's text:
element = driver.find_element_by_xpath("//*[#class='user-number' and . = '123']")
print(element.text)
The meta-question is, how to debug XPath expressions?
Well, for simple ones like these, it's really best to just stare at them till you see the problem. Check the spelling of names, check namespaces, check whitespace issues. At least it's easier than debugging regular expressions.
For more complex XPaths, try breaking them up. Remove a predicate and see if that makes a difference. Or work in reverse, build up the path expression by adding conditions, checking at each stage that it still finds something.
If you're really seriously into XPath, consider schema-aware processing: this will match your XPath expression against a schema to make sure it makes sense.
Consider using a visual XPath processor for debugging. There are a number around. I use the XPath processor in oXygen (though not really for debugging the XPath, more for discovering the content of the document, but those tasks often need to be done together.)