Could not evaluate XPath (Behat/Mink) - xpath

I'm using the following function:
/**
* Click on the element with the provided xpath query
*
* #When /^I click on the element with xpath "([^"]*)"$/
*/
public function iClickOnTheElementWithXPath($xpath)
{
$session = $this->getSession(); // get the mink session
$element = $session->getPage()->find('xpath',$session->getSelectorsHandler()->selectorToXpath('xpath', $xpath)); // runs the actual query and returns the element
// errors must not pass silently
if (null === $element) {
throw new \InvalidArgumentException(sprintf('Could not evaluate XPath: "%s"', $xpath));
}
// ok, let's click on it
$element->click();
}
in my FeatureContext.php trying to click on a button with the following XPath (the Behat Step is): When I click on the element with XPath
//html/body/div[4]/div/div/div/div[2]/div[2]/div[4]/div/div/div/div[2]/ol/li/span[4]/a[1]
Firebug is happy with this XPath, but behat is giving me the error:
Could not evaluate XPath: "//html/body/div[4]/div/div/div/div[2]/div[2]/div[4]/div/div/div/div[2]/ol/li/span[4]/a[1]"
What am I doing wrong?
here is an example of the Behat on w3schools, trying to click on the "Try it yourself" button":
Feature: xpath try on w3schools.com/tags/att_input_src.asp
Scenario: click button on xpath
#javascript
When I go to "/tags/att_input_src.asp"
And I click on the element with xpath "/html/body/div/div[3]/div[6]/div/a[1]"
And I wait 5 seconds
Then I should be on "tags/tryit.asp?filename=tryhtml_input_src"
gives the same error, could not evaluate xpath, the xpath on Firebug shows the correct button...

I had the same problem. It appears that you need to ommit /html/body. For me
//div[2]/div/div[2]/div/table/tbody/tr/td[3]
works fine.

Related

Click on an element which has a specific attribute value in Cypress

I am writing this code for an element that has an attribute value "123". Since there are many products on that page with the wishlist button. But I want to click on the wishlist button for this specific product id(123)
but I recieve an error saying
cy.click() can only be called on a single element.
Your subject contained 53 elements.
Pass { multiple: true } if you want to serially click each element.
Can someone help here?
cy.xpath('//div[#id="filterProducts"]//div[#data-wish-list-entry-number]').then(thisProduct => {
if (
(cy.wrap(thisProduct)
.invoke('attr', 'data-wish-list-entry-number')
.should('eq', '123') ))
{
cy.wrap(thisProduct)
.click()
}
You don't need the if(), just add the attribute value 123 in the selector.
Same way as you have in [#id="filterProducts"]
with XPath
cy.xpath('//div[#id="filterProducts"]//div[#data-wish-list-entry-number="123"]')
.click()
with Cypress get
cy.get('div[id="filterProducts"] div[data-wish-list-entry-number="123"]')
.click()
also
cy.get('div#filterProducts div[data-wish-list-entry-number="123"]')
.click()
If it is the first of the list you can use first:
cy.get("value").first().click();
If is not the first but you know the element number use eq:
cy.get("value").eq(40).click();

Set div value of WebElement with Selenium Webdriver

I want to set new value of div element by using Selenium FirefoxDriver in Java:
<div my-div-name="lastname">
<p>Smith</p>
</div>
I have successfully retrieved the div element (as WebElement) by use of XPATH expression and have also been able to get current value Smith by use of getText() method. However, there is no setText() method of an WebElement. So I have in stead tried to execute JavaScript:
driver.executeScript("arguments[0].value = 'Foo Bar'", element);
but nothing happens. New getText() call still returns Smith.
Any tip on how to set the value successfully?
Solution is to set innerHTML property like this:
driver.executeScript("arguments[0].innerHTML = arguments[1]", element, text);
I have tried to do this several times, but i wrote innerHtml and not innerHTML so be aware of casing when setting the property.

Checking Text exist or not?

Say I am on StackOverFlow "All Questions" page.
I want to search for a user say "user2402616" (which is present on 3rd page) on first page.
If not present then click on next button until it is found.
I tried below code using Xpath but getting error.
boolean bPres = driver.findElement(By.xpath("//a[contains(text(),'user2402616')]")).isDisplayed();
System.out.println(bPres);
while (!bPres) {
driver.findElement(By.xpath("//a[contains(text(),'next')]")).click();
}
Since the xpath has text in both the cases i.e for clicking on the user and the next button . You can use the By.linkText method and pass in the value which you want to click
boolean bPres = driver.findElement(By.linkText("user2402616")).isDisplayed();
System.out.println(bPres);
while (!bPres) {
driver.findElement(By.xpath("next").click();
}

How can I check if some text exist or not in the page using Selenium?

I'm using Selenium WebDriver, how can I check if some text exist or not in the page? Maybe someone recommend me useful resources where I can read about it. Thanks
With XPath, it's not that hard. Simply search for all elements containing the given text:
List<WebElement> list = driver.findElements(By.xpath("//*[contains(text(),'" + text + "')]"));
Assert.assertTrue("Text not found!", list.size() > 0);
The official documentation is not very supportive with tasks like this, but it is the basic tool nonetheless.
The JavaDocs are greater, but it takes some time to get through everything useful and unuseful.
To learn XPath, just follow the internet. The spec is also a surprisingly good read.
EDIT:
Or, if you don't want your Implicit Wait to make the above code wait for the text to appear, you can do something in the way of this:
String bodyText = driver.findElement(By.tagName("body")).getText();
Assert.assertTrue("Text not found!", bodyText.contains(text));
This will help you to check whether required text is there in webpage or not.
driver.getPageSource().contains("Text which you looking for");
You could retrieve the body text of the whole page like this:
bodyText = self.driver.find_element_by_tag_name('body').text
then use an assert to check it like this:
self.assertTrue("the text you want to check for" in bodyText)
Of course, you can be specific and retrieve a specific DOM element's text and then check that instead of retrieving the whole page.
There is no verifyTextPresent in Selenium 2 webdriver, so you've to check for the text within the page source. See some practical examples below.
Python
In Python driver you can write the following function:
def is_text_present(self, text):
return str(text) in self.driver.page_source
then use it as:
try: self.is_text_present("Some text.")
except AssertionError as e: self.verificationErrors.append(str(e))
To use regular expression, try:
def is_regex_text_present(self, text = "(?i)Example|Lorem|ipsum"):
self.assertRegex(self.driver.page_source, text)
return True
See: FooTest.py file for full example.
Or check below few other alternatives:
self.assertRegexpMatches(self.driver.find_element_by_xpath("html/body/div[1]/div[2]/div/div[1]/label").text, r"^[\s\S]*Weather[\s\S]*$")
assert "Weather" in self.driver.find_element_by_css_selector("div.classname1.classname2>div.clearfix>label").text
Source: Another way to check (assert) if text exists using Selenium Python
Java
In Java the following function:
public void verifyTextPresent(String value)
{
driver.PageSource.Contains(value);
}
and the usage would be:
try
{
Assert.IsTrue(verifyTextPresent("Selenium Wiki"));
Console.WriteLine("Selenium Wiki test is present on the home page");
}
catch (Exception)
{
Console.WriteLine("Selenium Wiki test is not present on the home page");
}
Source: Using verifyTextPresent in Selenium 2 Webdriver
Behat
For Behat, you can use Mink extension. It has the following methods defined in MinkContext.php:
/**
* Checks, that page doesn't contain text matching specified pattern
* Example: Then I should see text matching "Bruce Wayne, the vigilante"
* Example: And I should not see "Bruce Wayne, the vigilante"
*
* #Then /^(?:|I )should not see text matching (?P<pattern>"(?:[^"]|\\")*")$/
*/
public function assertPageNotMatchesText($pattern)
{
$this->assertSession()->pageTextNotMatches($this->fixStepArgument($pattern));
}
/**
* Checks, that HTML response contains specified string
* Example: Then the response should contain "Batman is the hero Gotham deserves."
* Example: And the response should contain "Batman is the hero Gotham deserves."
*
* #Then /^the response should contain "(?P<text>(?:[^"]|\\")*)"$/
*/
public function assertResponseContains($text)
{
$this->assertSession()->responseContains($this->fixStepArgument($text));
}
In c# this code will help you to check whether required text is there in webpage or not.
Assert.IsTrue(driver.PageSource.Contains("Type your text here"));
You can check for text in your page source as follow:
Assert.IsTrue(driver.PageSource.Contains("Your Text Here"))
In python, you can simply check as follow:
# on your `setUp` definition.
from selenium import webdriver
self.selenium = webdriver.Firefox()
self.assertTrue('your text' in self.selenium.page_source)
Python:
driver.get(url)
content=driver.page_source
if content.find("text_to_search"):
print("text is present in the webpage")
Download the html page and use find()
boolean Error = driver.getPageSource().contains("Your username or password was incorrect.");
if (Error == true)
{
System.out.print("Login unsuccessful");
}
else
{
System.out.print("Login successful");
}
JUnit+Webdriver
assertEquals(driver.findElement(By.xpath("//this/is/the/xpath/location/where/the/text/sits".getText(),"insert the text you're expecting to see here");
If in the event your expected text doesn't match the xpath text, webdriver will tell you what the actual text was vs what you were expecting.
string_website.py
search string in webpage
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
browser = webdriver.Firefox()
browser.get("https://www.python.org/")
content=browser.page_source
result = content.find('integrate systems')
print ("Substring found at index:", result )
if (result != -1):
print("Webpage OK")
else: print("Webpage NOT OK")
#print(content)
browser.close()
run
python test_website.py
Substring found at index: 26722
Webpage OK
d:\tools>python test_website.py
Substring found at index: -1 ; -1 means nothing found
Webpage NOT OK
You can check a source code if the text exists:
source_code = driver.page_source
if "Im not a Robot" not in source_code:

Selecting Ajax Dropdown suggestion list using Selenium for Firefox

How can i select Ajax Dropdown suggestion list item using selenium code for firefox??
My problem is :the Ajax dropdown list is visible but it is not selected and next steps gets stuck.
May be selenium is waiting for something.
the list that page populates is dynamic and in bla bla tags.
Please help with a example code.
How can i use waitfor* here.
Remember i am not using firefox ide but i am writing a code.
Please help.
I had a similar problem whereby, selenium was able to find the dropdown menu but was unable to click on the visible text. I later found out that there was an Ajax call that was populating the dropdown menu data and as a result selenium seemed to not be able to select the intended visible text because the list items had not been fully populated. That is, by the time the script was selecting my option value, Ajax had not completely loaded the menu options. Here's my solution:
public void nameOfCollegeList(String optionItem) {
// declare the dropdownMenu web element
WebElement dropDownMenu = driver.findElement(By.cssSelector("#CollegeNames"));
// click on the dropdownMenu element to initiate Ajax call
dropDownMenu.click();
// keep checking the drop down menu item list until you find the desired text that indicates that the menu has
// been fully loaded. In this example I always expect "Other (please specify)" to be the last item in the drop down menu.
// If I don't find the expected last item in the list in my if condition, execute the else condition by calling the
// same method(recursively). Please note that if the "if" statement is never satisfied then you'll end up with an
// infinite loop.
if (dropDownMenu.getText().contains("Other (please specify)")) {
new Select(dropDownMenu).selectByVisibleText(optionItem);
}
else {
nameOfCollegeList(optionItem);
}
}
i am little confused with your question at " :the Ajax dropdown list is visible but it is not selected "
this sounds like that the element is disabled. (Java coding)
if so selenium.isElementDisabled()
if not then,
1) programming laguage solution using while loop and isElementPresent() OR isElementDisabled()
//trigger the Ajax request and then
long initialTime = System.currentTimeMillis();
do{
thread.sleep(1000);
}while((!selenium.isElementPresent("AjaxElement")) && (System.getCurrentTimeMillis() - initialTime <= 5000)) ;
//some thing like above for client programming solution...but for,
2) selenium's inbuilt solution
we have a method called waitForCondition("java script to be executed", "time out value");
this method loops the javascript statement until it returns true or the supplied time out occurs
here the important thing is analyzing the application/Ajax element to find out which particular condition of the element changes.
from your explation my guess is this, display=none will be changed to display=block OR
disabled=true will be changed to disabled=false OR isReadOnly will be changed to no such attribute ect.....(you need to figure out this)
and then, use this attribute = value to build a javascript function as ,
selenium.waitForCondition("window.document.getElementById('AJAX ELEMENT').disabled == 'false'", "3000");
you can work out the above statement however you want in your programming language.
try {
//do the action which triggers the Ajax call
selenium.waitForCondition("window.document.getElementById('AJAX ELEMENT[drop down element]').disabled == 'false'", "3000");
//OR
selenium.waitForCondition("window.document.getElementById('AJAX ELEMENT').disabled == 'false'", "3000");
}
catch(SeleniumException se)
{
if((se.getMessage()).toLowerCase().contains("timed out")
throw //..some a custom exception however your organisation requires
}
selenium.select("drop down element id", "option id");
and so on.....

Resources