Having trouble identifying popover text - java

I'm having trouble coming up with a cssSelector statement for the following control.
<div class="popover-content">
<i class="icon-time"></i>
<h3>24 Hours Risk Free!</h3>
<p>
Book now and
<strong>cancel for free up to 24 hours</strong>
</p>
</div>
I need to simply write a test that verifies this warning exists. Anyone have any ideas?

You can use JQuery
<a id="btnT" class="btn btn-xs btn-warning">Test</a>
var x = false;
$(document).ready(function(){
$('#btnT').popover({
placement: 'bottom',
title: '${trainingDetail.title}',
content: '${trainingDetail.description}',
trigger: 'click',
html : true,
container: 'body'
}).hover(function() {
if (x) {
$(this).popover('hide');
x = false;
}
else {
$(this).popover('show');
x = true;
}
});
});

Just find out the div tag using class and get its text. It will get you all the text in it for the h3 and p tags.
driver.findElement(By.className("popover-content")).getText();
Assuming you are able to already hover over it etc etc... Use the Actions class and moveToElement method.

Related

Toggle show hide for multiple divs with one button

I am trying to toggle multiple divs with same class via one button. At the moment, only the first div is doing the job and the rest gets ignored. I tried to change .getElementById to .getElementsByClassName but it also doesn´t do the trick. Can you please help? Here is my code. I´m trying since 2 days. :/
Code for Button:
<input onclick="change();myFunction()" type="button" value="Zeige Features" id="myButton1"></input>
Code for changing the text of button when clicked to "hide" / "show" (in German):
<script>function change() // no ';' here
{
var elem = document.getElementById("myButton1");
if (elem.value=="Zeige Features") elem.value = "Verstecke Features";
else elem.value = "Zeige Features";
}</script>
The problem should be perhaps here. That´s the code for toggling the divs but only the first div does it:
<script>function myFunction() {
var x = document.getElementById("toggle-div");
if (x.style.display === "block") {
x.style.display = "none";
} else {
x.style.display = "block";
}
} </script>
Hope u can help me, and thanks!
Remove the semicolon from your onclick and add a space.
//New code
<input onclick="change() myFunction()" type="button" value="Zeige Features" id="myButton1"></input>
The text of Button will change pretty easily onclick.
<script>
function change()
{
var elem = document.getElementById("myButton1");
if (elem.value=="Zeige Features") elem.value = "Verstecke Features";
else elem.value = "Zeige Features";
}//function closed
</script>
Use getElementsByClass, it will give an array, so loop through the array, and change the style of each div one by one.
<script>
function myFunction()
{
var x = document.getElementsByClass("toggle-div");
for( var i=0;i<x.length;i++)
{
if (x[i].style.display === "block") {
x[i].style.display = "none";
} else {
x[i].style.display = "block";
}
}
}
</script>
You can use any loop other then for also, or you can use map()
there are several problems here.
First of all you should get your element by class as it:
document.getElementsByClassName("name-of-toggle-divs-class");
this will return an HTMLCollection, so you want to cast it to an array, like this:
Array.from(document.getElementsByClassName("name-of-toggle-divs-class"));
And then apply the style change to ALL of the elements. Resuming:
function myFunction(){
const divArray = Array.from(document.getElementsByClassName("name-of-toggle-divs-class"));
//Detecting the style you're going to use
const displayStyle = divArray[0].display.style === 'block' ? 'none' : 'block';
divArray.forEach(div => {
div.style.display = displayStyle;
});
You should use class identifier because and id would suggest you have only one item. Let me know if you have problems.
You could also think of toggling class from your items defining class as:
.div-of-toggle-divs-class{
//some attributes
display: block;
&.invisible{
display: none;
}
}
To do this just follow the same process as above and use the toggleClass method on the divArray elements. Try this:
<head>
<style>
.myClass {
border: 1px solid black;
margin-top: 2px;
width: 100%;
}
</style>
<script>
function myFunction(){
const divArray =
Array.from(document.getElementsByClassName("myClass"));
//Detecting the style you're going to use
const displayStyle = divArray[0].display.style === 'block' ? 'none' : 'block';
divArray.forEach(div => {
div.style.display = displayStyle;
});
</script>
</head>
<body>
<div class="myClass"></div>
<div class="myClass"></div>
<div class="myClass"></div>
<button type="button" onclik="myFunction()">CLICK ME</button>
</body>
Okay,
this was a pain in the ass but I think with a lot of workaround I solved it. Here is what I wanted to achive. Having three buttons and three divs. When I click one button alls three divs disappear and all three buttons change text to "hide". When click again, vice versa. I hope this helps everyone out there. I think to trigger all "classes" is in css much easier. These were my first steps in javascript and it was as difficult as chinese for me (don´t speak it :)).
// Toggle all buttons texts
function change() {
var x = document.querySelectorAll("#button");
var i;
for (i = 0; i < x.length; i++) {
if (x[i].value == "Zeige Features") {
x[i].value = "Verstecke Features";
} else {
x[i].value = "Zeige Features";
}
}
}
// Toggle show and hide divs
function showhide() {
var x = document.querySelectorAll("#toggle-div");
var i;
for (i = 0; i < x.length; i++) {
if (x[i].style.display === "block") {
x[i].style.display = "none";
} else {
x[i].style.display =
"block";
}
}
}
<!--Inserting 3 buttons-->
<input onclick="change();showhide()" type="button" value="Zeige Features" id="button"></input>
<input onclick="change();showhide()" type="button" value="Zeige Features" id="button"></input>
<input onclick="change();showhide()" type="button" value="Zeige Features" id="button"></input>
<!--Inserting 3 divs-->
<div id="toggle-div"> div 1 </div>
<div id="toggle-div"> div 2 </div>
<div id="toggle-div"> div 3 </div>
Thanks #pikachu_on_acid. Youre approach was the right one but still I had issues with it. Don´t wonder if you have to click two times at the beginning when u want to hide the divs. In my site they are first hidden, so they appear fist. If you want to reverse that just change the values from "block" "none" "block" to "none" "block" "none" in the java code.
Thanks for your help and regards!

Thymleaf Spring MVC Button executes Java method

So this is what I have in my HTML file:
<ul>
<th:block th:object="${Post}">
<li class="post" th:each="Post : ${Posts}">
<p th:text ="${Post.getPostText()}"></p>
<button th:onclick = "${Post.upvote()}">Upvote</button>
<button th:onclick = "${Post.downvote()}">Downvote</button>
<p th:text = "${Post.getPostVotes()}"></p>
</li>
</th:block>
</ul>
I want the button to execute a method within the Post class. I'm not sure if I'm using the correct Thymeleaf 'tag'. Right now, when the page loads, it executes the post upvote and downvote methods.
Can anyone help out? I have a feeling I'm using the wrong Thymeleaf Tag.
You need to do a post or get request to invoke those methods. That will only work in JSF, but you can execute the method before de page is rendered as html.
for example this line
<p th:text ="${post.getPostText()}"></p>
will be executed before the page is rendered .
What I do here is to hide a form for both action, two buttons with a name attributes and pass some sort of identifier to know witch entity I'm updating.
In my controller would have two methods that responds to each parameter and return a view or JSON.
So they reason I couldn't do what I wanted to do was because Thymeleaf generates HTML as before the pages loads. It doesn't sit in the HTML waiting to be triggered. I ended up changing the HTML to go to a different URL that would be unique to the post.
<ul>
<th:block th:object="${Post}">
<li class="post" th:each="Post : ${Posts}">
<p th:text ="${Post.getPostText()}"></p>
<a th:href = "#{/post?id={id}&vote=1(id=${Post.getPostId()})}">Upvote</a>
<a th:href = "#{/post?id={id}&vote=0(id=${Post.getPostId()})}">Downvote</a>
<p th:text = "${Post.getPostVotes()}"></p>
</li>
</th:block>
</ul>
And this was the corresponding java code in my controller that would update the object:
#RequestMapping(value = "/post", params = {"id", "vote"})
public String PostVoting(#RequestParam("id") Long id, #RequestParam("vote") int vote)
{
if (currentUser.voteOnPost(id.toString())){
return "redirect:/home";
}
if(vote == 1){
int votes = thePostRepository.findById(id).get().getPostVotes() + 1;
thePostRepository.updateVotes(votes, id);
}
else{
int votes = thePostRepository.findById(id).get().getPostVotes() - 1;
thePostRepository.updateVotes(votes, id);
}
return "redirect:/home";
}
Also, this next part is important if you want to update things like I did:
#Transactional
#Modifying
#Query("UPDATE Post SET votes = :votes WHERE id = :id")
void updateVotes(#Param("votes") int votes, #Param("id") Long id);

How do I read the element from a dropdown menu of a html?

I am parsing the following html by Selenium FirefoxDriver -
<div id="primaryNav" style='background: url("https://images-na.ssl-images-amazon.com/images/G/31/associates/network/08-ui-elements/primaryNavBackground._V161555288_.gif") repeat-x bottom;'>
<div id="menuh">
<ul>
<li style="visibility:hidden;
height:24px"/>
<li style='background:url("https://images-na.ssl-images-amazon.com/images/G/31/associates/network/08-ui-elements/tab-unslected-right._V161557413_.gif") no-repeat right top;'>
▼</span>
<div class="parent">
<div class="dropdownlinks">
<div class="subitem">Product Links</div><div class="subitem">Banner Links</div><div class="subitem">Link to Any Page</div><div class="subitem">Link Checker</div>
</div>
</div>
</li>
<li style='background:url("https://images-na.ssl-images-amazon.com/images/G/31/associates/network/08-ui-elements/tab-unslected-right._V161557413_.gif") no-repeat right top;'>
<a href="http://widgets.amazon.in/?_encoding=UTF8&store=httpswwwvanta-21&tag=httpswwwvanta-21" style='float:left;background:url("https://images-na.ssl-images-amazon.com/images/G/31/associates/network/08-ui-elements/tab-unslected-left._V161554471_.gif") no-repeat left top;'>Widgets</a>
</li>
<li style='background:url("https://images-na.ssl-images-amazon.com/images/G/31/associates/network/08-ui-elements/tab-unslected-right._V161557413_.gif") no-repeat right top;'>
<a href="/gp/advertising/api/detail/main.html" style='float:left;background:url("https://images-na.ssl-images-amazon.com/images/G/31/associates/network/08-ui-elements/tab-unslected-left._V161554471_.gif") no-repeat left top;'>Product Advertising API</a>
</li>
<li style='background:url("https://images-na.ssl-images-amazon.com/images/G/31/associates/network/08-ui-elements/tab-unslected-right._V161557413_.gif") no-repeat right top;'>
▼</span>
<div class="parent"><div class="dropdownlinks">
<div class="subitem"><a href="/gp/associates/network/reports/report.html?ie=UTF8&reportType=earningsReport" >Earnings Report</a>
</div><div class="subitem"><a href="/gp/associates/network/reports/report.html?ie=UTF8&reportType=ordersReport" >Orders Report</a>
</div><div class="subitem"><a href="/gp/associates/network/reports/report.html?ie=UTF8&reportType=linkTypeReport" >Link-Type Report</a>
</div><div class="subitem"><a href="/gp/associates/network/reports/report.html?ie=UTF8&reportType=trendsReport" >Daily Trends</a>
</div><div class="subitem"><a href="/gp/associates/network/reports/report.html?ie=UTF8&reportType=tagsReport" >Tracking ID Summary Report</a>
</div>
</div>
</div>
</li>
</ul>
</div>
</div>
I am trying to select the "Earnings Report" from the dropdown menu.
I tried like this --
dropDownButton: WebElement = driver.findElement(By.xpath(".//a[#href='https://affiliate-program.amazon.in/gp/associates/network/reports/report.html?ie=UTF8&reportType=earningsReport']"))
dropDownButton.click()
I also tried like this --
val dropDownButton = driver.findElement(By.linkText("Earnings Report"))
dropDownButton.click()
In both the cases, The code runs only when I hover my mouse over the dropdown menu. No manual click is required.
I also tried the following code which I am not sure if correct -
import scala.collection.JavaConversions._
def selectValueFromDropdown( value: String) = {
var options = driver.findElements(By.id("menuh"));
for(option <- options) {
if (value.equals(option.getText())) {
option.click()
}
}
}
selectValueFromDropdown("Earnings Report")
I am kinda lost here. Please suggest a solution in either Java or Scala.
EDIT: I get to this page after log-in from the main page. Can that be a problem?
Please try this:
First select the drop down and then select by value or Index-
Select drpdown = new Select(driver.findElement(By.xpath("Locator of the dropdown"));
drpdown.SelectByValue("Earning Report");
If "Earning Report" is a visible Text then-
drpdown.selectByVisibleText("Earning Report");
As you mentioned that you have to hover your mouse over the dropdown menu for it to work. Your menu also has sub-menus. So, before clicking the link you need to use the "perform" method of "Actions". In this manner it allows Selenium to spot a particular sub-menu while holding the menu. The code for that is:
val menuElement = driver.findElement(By.id("menuh"))
/* If the css selector used below does not match the element that
* fires the hover action then check which element fires it and update
* the selector */
val subMenuElement = driver.findElement(By.cssSelector("#menuh li:nth-child(5)"))
val earningsReportElement = driver.findElement(By.linkText("Earnings Report"))
val action = new Actions(driver)
action.moveToElement(menuElement).perform()
action.moveToElement(subMenuElement).perform()
action.moveToElement(earningsReportElement)
action.click()
action.perform()
try this-
driver.findElement(
By.xpath("//a[contains(#href,'earningsReport')]"))
.click();
The solution given by #Dagojvg worked after re-arranging the expressions.
import org.openqa.selenium.interactions.Actions
val action = new Actions(driver)
val menuElement = driver.findElement(By.id("menuh"))
action.moveToElement(menuElement).perform()
val subMenuElement = driver.findElement(By.cssSelector("#menuh li:nth-child(5)"))
action.moveToElement(subMenuElement).perform()
val earningsReportElement = driver.findElement(By.linkText("Earnings Report"))
action.moveToElement(earningsReportElement)
action.click()
action.perform()

Selenium driver - select the desired li item in the list

In a list of 8 Elements I would select the one that contains the search text in children div. I need this because the elements of the list changes order every time. Here I would like to select the one that contains the text "TITLE TO LISTEN". How do I scroll through the list and select the wish li?
Thanks in advance
Here one li:
...
<li id="3636863298979137009" class="clearfix" data-size="1" data-fixed="1" data-side="r">
<div class="userContentWrapper">
<div class="jki">
<span class="userContent">
TITLE TO LISTEN
</div>
<div class="TimelineUFI uiContainer">
<form id="u_0_b0" class="able_item collapsed_s autoexpand_mode" onsubmit="return window.Event && E" action="/ajax/ufi/modify.php" method="post" >
<input type="hidden" value="1" name="data_only_response" autocomplete="off">
<div class="TimelineFeedbackHeader">
<a class="ction_link" role="button" title="Journal" data-ft="{"tn":"J","type":25}" rel="dialog" href="/ajax/" tabindex="0" rip-style-bordercolor-backup="" style="" rip-style-borderstyle-backup="" >LISTEN</a>
</div>
</form>
</div>
</div>
</li>
</ol>
</div>
...
I tried this code, but it don't work because the elements ids change each time.
driver.findElement(By.xpath("//li[8]/div[2]/div/div[2]/form/div/div/span[2]/a")).click();
For example:
If text contain "TEXT TO LISTEN": li[3]/div[2]/div/div/div[2]/div/div/span
Link "listen" i want to click : li[3]/div[2]/div/div[2]/form/div/div/span[2]/a
here is number 3, but the order may change. I would first like to get that number and then click on the right link
Use this
driver.findElement(By.xpath("//li[contains(text(), 'Your text goes here')]"))
EDIT: just realised it's very old ques and you might have got ans by now, so for others who are looking for answer to this question.
You could get list of all li elements, and then search for specified text
for(int i=0; i< listOfLiElements.Count, i++){
if(listOfLiElements[i].FindElement(By.ClassName("userContent")).Text == "TITLE TO LISTEN")
{
correctElement = listOfLiElements[i].FindElement(By.TagName("a"));
i =listOfLiElements.Count;
}
}
Well, then just iterate through for each and ask if the current element has the right text inside it.
List<Element> listOfLiTags = driver.findElement(By.Id("yourUlId")).findElements(By.TagName("li"));
for(Element li : listOfLiTags) {
String text = li.getElement(By.ClassName("userContent").getText();
if(text.equals("TITLE TO LISTEN") {
//do whatever you want and don't forget break
break;
}
}
Note that this is much more easier with CssSelector API.
List<Element> listOfSpans = driver.findElements(
By.CssSelector("ul[id=yourId] li span[class=userContent]");
Now just iterate and ask for the right text:)
You can try this :
public void ClickLink()
{
WebElement ol =driver.findElement(By.id("ol"));
List<WebElement> lis=ol.findElements(By.tagName("li"));
ArrayList<String> listFromGUI=new ArrayList<>();
for(int i=0;i<lis.size();i++)
{
WebElement li=ol.findElement(By.xpath("//ol[#id='ol']/li["+(i+1)+"]/div[2]/div/div/div[2]/div/div/span"));
if(li.getText().trim().equals("TEXT TO LISTEN"))
{
WebElement link=ol.findElement(By.xpath("//ol[#id='ol']/li["+(i+1)+"]/div[2]/div/div[2]/form/div/div/span[2]/a"));
if(link.getText().trim().equals("LISTEN"))
{
link.click();
break;
}
}
}
}

Flex/Flash 4 ExternalInterface.call - trying to get a string from HTML to Actionscript

I need to obtain a string from HTML and put it into Actionscript.
the actionscript:
import flash.external.ExternalInterface;
protected function getUserName():void{
var isAvailable:Boolean = ExternalInterface.available;
var findUserName:String = "findUserName";
if(isAvailable){
var foundUserName:String = ExternalInterface.call(findUserName).toString();
Alert.show(foundUserName);}}
the javascript:
function findUserName() {
var label = document.getElementById("username-label");
if(label.value != ""){
alert("the name in the box is: " + label.value);
return label.value;}
else
return "nothing in the textbox";}}
the JSP:
<%IUserSession userSession = SessionManager.getSession();%>
<logic:notEmpty name="userSession">
<logic:notEqual value="anonymous" name="userSession" property="userLoginId">
<td align="right" width="10%" >
<input id="username-label" type="text" value="<bean:write name="userSession" property="userLoginId"/>" />
</td>
</logic:notEqual>
</logic:notEmpty>
the rendered HTML:
<td align="right" width="10%">
<input id="username-label" type="text" value="a-valid-username" />
</td>
when the javascript execution hits
var label = document.getElementById("username-label");
a null is returned and crashes, no alert shows no error message is shown.
I can successfully do a search firefox DOM Inspector by "username-label" (document.getElementById())
The only alert box that pops up is the action script alert box and the contents are blank.
firfox 3.5 windows, container is Tomcat.
Please advise, and thank you in advance.
import flash.external.ExternalInterface;
public function getUserName():void{
var isAvailable:Boolean = ExternalInterface.available;
//var findUserName:String = "findUserName";
if(isAvailable){
ExternalInterface.call("findUserName");
}
}
Now create a button and call this function getUserName and now try to put a alert message in JavaScript and see if that calls.
Make the method Public and let us know whether you are able to call the JavaScript method name. See the changes i made in u r function
Note: Protected and Private will also work, this is just for testing.
More Update:
function findUserName() {
// We are checking down initially itself.
if (!document.getElementById) return;
var label = document.getElementById(username-label);
alert(label);
if(label.value != ""){
alert("the name in the box is: " + label.value);
return label.value;}
else
return "nothing in the textbox";}}
Update your JavaScript function to above and let me know.
Thanks.

Categories

Resources