Checking Text exist or not? - xpath

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();
}

Related

Selecting an element not equal to a certain string

I am trying to select an incorrect answer (radio button) to get an error message to appear, but the answers are random (except the correct answer).
How can I say get the radio buttons, and then click one that does not equal "correct answer" using cypress assertions?
cy.get('[data-cy="multipleChoiceQuestionAnswer"]')
.should('not.contain', 'correct answer')//.find('label').not('corect answer')//.not.includes('correct answer')
.click()
I would like to be able to select one of the two radio buttons for the incorrect answers, right now I can only select the correct answer.
well:
be aware that .should('not.contain', 'correct answer') is an assertion, is not a way to filter/get some elements.
It's, essentially, just a way to check (aka "assert") that something is like you expect it to be.
An assertion like yours is useful just to get the Cypress log print something like this
Read it like if you are telling
"Ehy Cypress, I selected an element, could you check that it doesn't contain the correct answer, please?"
What are assertions useful for? They aren't useful when everything goes right but when the test goes wrong.
Because without assertions, you can find yourself behind a broken test with Cypress telling you that "there isn't the element" but you can't know which element Cypress isn't finding.
Placing some "key point" assertions allows you to understand why a test failed in short time.
Anyway: if your HTML is something like this
<div data-cy="multipleChoiceQuestionAnswer"><label>correct answer<input type="checkbox"/></label></div>
<div data-cy="multipleChoiceQuestionAnswer"><label>no<input type="checkbox"/></label></div>
<div data-cy="multipleChoiceQuestionAnswer"><label>nope<input type="checkbox"/></label></div>
you can accomplish your goal making:
cy.get('[data-cy="multipleChoiceQuestionAnswer"]').then(els => {
// `els` is a jQuery instance, let's parse the various elements
let $el;
for(let i = 0, n = els.length; i < n; i++) {
// it transforms every element in a jQuery instance
$el = Cypress.$(els[i]);
// it uses jQuery to get the label text
if($el.find("label").text() !== "correct answer") {
// it stops as soon as the answer isn't the correct one
break;
}
}
// returns the element to be clicked
return $el.find("input");
})
// it assert about it (to have a useful hint in the Cypress command log)
.should("not.contain", "correct answer")
// clicks it
.click();
I hope the code is self-explanatory (in case it isn't, ask me some more clarifications) 😊

Can Not Click The Same Element Class Using Watir

I have the following screen:
And I use the following Ruby script to click the "Add New" button:
vendorTab = driver.a id: "tab-master-tab-vendor"
vendorTab.wait_until_present
if vendorTab.exists?
vendorTab.click
end
addNewButton = driver.button class: ['btn btn-primary']
addNewButton.wait_until_present
if addNewButton.exists?
addNewButton.click
end
But, when I move to another tab and try to click the same "Add New" button, the Ruby script doesn't work.
Is there anything wrong with my Ruby code?
buildingTypeTab = driver.a id: "tab-master-tab-building"
buildingTypeTab.wait_until_present
if buildingTypeTab.exists?
buildingTypeTab.click
end
addNewButton = driver.button class: ['btn btn-primary']
addNewButton.wait_until_present
if addNewButton.exists?
addNewButton.click
end
I Appreciate your help. Thank you very much.
I guess all of these tabs are part of the same web page? I.e., all in the same HTML?
If that is the case, driver.button class: ['btn btn-primary'] is going to stop when it finds the first instance in the HTML, but that isn't the button you are looking for every time (it's the button in the first tab, where your script worked as you expected).
The best options in my mind are
find a way to uniquely identify the button in each tab (for example, use id instead of class if possible), or
pull all the buttons into a collection and click the button using its collection index after you figure out which index aligns with each tab. For example,
button_collection = browser.buttons(:class, ['btn', 'btn-primary'])
button_collection[2].click # Will click the 3rd button in the collection
After reading the suggestions from pjd,
I modified it a bit and got it working like this:
buildingTypeTab = driver.a id: "tab-master-tab-building"
buildingTypeTab.wait_until_present
if buildingTypeTab.exists?
buildingTypeTab.click
end
addNewButton = driver.button(:class => ['btn btn-primary'], :index => 2)
addNewButton.wait_until_present
if addNewButton.exists?
addNewButton.click
end
As pjd said, yes all these tabs are part of the same HTML
Thank you.

Could not evaluate XPath (Behat/Mink)

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.

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.....

How to click on an AutoCompleteExtender with Watin

For my acceptance testing I'm writing text into the auto complete extender and I need to click on the populated list.
In order to populate the list I have to use AppendText instead of TypeText, otherwise the textbox looses focus before the list is populated.
Now my problem is when I try to click on the populated list. I've tried searching the UL element and clicking on it; but it's not firing the click event on the list.
Then I tried to search the list by tagname and value:
Element element = Browser.Element(Find.By("tagname", "li") && Find.ByValue("lookupString"));
but it's not finding it, has anyone been able to do what I'm trying to do?
The shorter version of that is:
string lookupString = "string in list";
Element list = Browser.Element("li", Find.ByText(new Regex(lookupString)));
list.MouseDown();
Regexs will do a partial match so you don't need to specify .* either side and use string.Format. This assumes however that the lookupString doesn't contain any characters special to Regexs, they'd need to be escaped.
In case someone has the same problem. It works with the next code:
string lookupString = "string in list";
Regex lookup = new Regex(string.Format(".*{0}.*", lookupString));
Element list = Browser.Element("li", Find.ByText(lookup));
list.MouseDown();

Resources