nightwatch select current element's inner div - nightwatch.js

i'm new to nightwatch and was wondering if there's any good way to select the inner element of a current element and then get the text? Assuming i have the following..and i'm trying to retrieve the text inside (a) tags of each (li).
so i would like to get 'text to retrieve' and 'text to retrieve 2'.
...
<div class="mywrapperhere">
<ul>
<li>
<a>.....
<div>text to retrieve</div>
</a>
</li>
<li>
<a>.....
<div>text to retrieve 2</div>
</a>
</li>
<li>...
...
</div>
I'm thinking along these lines..
module.exports = {
'Demo test 1' : function (browser) {
....
//some sort of selector then gets from the anchor list
...'.mywrapperhere li a') : {
..
//for each element of the anchor..
{
//is there anyway to get it through something like
element.('div').innerHTML eg..
//or am i forced to use browser.execute( ...getElementsByTag method
//to achieve this?
}
}
browser.end();
}
};
Looking at the nightwatch api, i couldn't find anything allows me to do that. I'm particularly looking at the 'Element State' examples that doesn't seem to have a way for me to select the current element state's child element :
http://nightwatchjs.org/api/elementIdAttribute.html
The reason why i had to loop through the anchor tag level is because i'll need to retrieve a few more data besides the one from div tag, thanks!

You can use elementIdElement and elementIdText to get text from a child element. First you can get all the li elements by using .elements(). Then you use elementIdElement to get a child element. Then you can use elementIdText to get the text of this child element. Here is an example that will allow you to get the text of both list items in your snippet and log the values to the console.
browser.elements('css selector', 'li', function(listItems) {
listItems.value.forEach(function(listItem) {
browser.elementIdElement(listItem.ELEMENT, 'css selector', 'a', function(anchor) {
browser.elementIdText(anchor.ELEMENT, function(text) {
console.log(text.value);
});
});
}, browser); //have to pass in browser for scoping
});

Related

Selenium not grabbing the selected element but the one loaded by Javascript

I am using selenium to grab the href attribute of the a tag. But my code is not grabing the "/pros/52698281" as it should.
Is it because my code is wrong or because some javascript is loading dynamically another url ? Could he ?
Here is the html :
<article class="bi-bloc blocs clearfix bi-pro visited" id="bi-bloc-014805042600000000C0001" data-pjtoggleclasshisto="{"idbloc": {"id_bloc": "014805042600000000C0001", "no_sequence": "" }, "klass":"visited" }">
<div class="zone-bi">
<a class="visible-phone mob-zone-pro pj-lb pj-link" data-pjsearchctx-sethref="" href="/pros/52698281" data-pjstats="{"idTag":"MOB-ZONE-PRO","pos":54,"type_bi":"pro","genreBloc":"1","pjscript":"xt_click({},'C','{%xtn2}','LR_BI::zone_identification::info{%pjstats.type_bi}::identification_pro','A');"}">
<span class="not-visible">
XXXXXXXXXXX
</span>
</a>
I am using this code to grab the href attribute.:
elements = driver.find_elements(:css, "article.bi-bloc div.zone-bi a.visible-phone")
elements.each do |e|
p e.attribute("href")
end
Here is the javascript code that, I think, loads dynamically another url (the one printing in my terminal).
<script type="text/javascript">
var pj_searchctx = {
"1989516432": {
"form": {
"quoiqui": "climatisation",
"ou": "paris-75",
"proximite": 0
},
"search": {
"technicalUrl":"/annuaire/chercherlespros?quoiqui=climatisation&ou=paris-75&idOu=L07505600&page=3&contexte=BupKFuSlIjbFtxi68rty83eKL16bkxx3e0d5jKAkSaA%3D&proximite=0&quoiQuiInterprete=climatisation",
"breadcrumb": "Retour aux résultats",
"stats": {
"idTag": "VERS-LR-RESULTATS"
}
}
}
};
Any idea how I can do ?
Since you're using direct children in your CSS selector, try using this instead of yours (with >):
"article.bi-bloc > div.zone-bi > a.visible-phone"
This matches more specifically the element your looking for.

How to refer Element using xpath inside multiple <li> that in turn contains <a> tag

How can i refer multiple elements present under li tag using xpath?
<div id="accordian">
<ul>
<li>
<h3 class="classroom"></h3>
<ul style="display: block;">
<li>name1</li>
<li>name2</li>
<li>name3</li>
<li>name4</li>
</ul>
</li>
i am using Selenium Webdriver, I tried following code to refer the element, but it returns a blank value.
List<WebElement> listelement=driver.findElements(By.xpath("//div[#id='accordian']/ul/li/ul/li"));
for(WebElement list: listelement)
{
System.out.println(list.getText());
}
List<WebElement> list=driver.findElements(By.xpath("//div[#id='accordian']/ul/li/ul/li"));
just add a tag at end of your xpath, that all this will work
//div[#id='accordian']/ul/li/ul/li/a"
*** This is a comment as I don't have access to Comments section ****
Hi,
Limit xpath till /ul and don't use /li. It will return list and then iterate over the child elements.
xpath("//div[#id='accordian']/ul/li/ul")
I doubt about the Xpath you tried, But below is the way you can achieve it.
List<WebElement> list=driver.findElements(By.xpath("//div[#id='accordian']/ul/li/ul/li"));
System.out.println("No of names present="+ list.size());
// use of for loop for iteration
for(int i=0;i<list.size();i++)
{
System.out.println(list.get(i).getText());
}
System.out.println("-------------------------");
//use of for each for iteration
for(WebElement wb: list)
System.out.println(wb.getText());
Do getText() on a tag elements. I always prefer using css over xpath. So here is my solution,
By byCss = By.cssSelector("#accordian>ul>li>ul>li>a");
List<WebElement> listElement = driver.findElements(byCss);
for(WebElement list: listElement)
{
System.out.println(list.getText());
}
I got the same problem and struggled with it for few days. You can use href tag as well to fetch the elements. Also You can try using 'a' tag. It will be something like this:
List<WebElement> listelement=driver.findElements(By.xpath("//div[#id='accordian']/ul/li/ul/li/a"));
for(WebElement list: listelement) {
String name= list.getAttribute("href");
System.out.println(name);
}
---should be comment, but don't have enough reputation---
I tried your solution on given HTML,
for me it is working fine for chromedriver and firefox.(printing all four values from list)
for InternetExplorer driver i am not able to get values, but it it because listElement.size() is 0
You can try
element.getAttribute("value") or elem.getAttribute("innerHTML");
to check what is happening here.
swapnil, your code with xpath is working for me, I get all the 4 elements, still you can try this as well
List<WebElement> listElements = driver.findElements(By.tagName("a"));
for(WebElement a : listElements){
System.out.println(a.getText());
}

using foundation 5 joyride with tabs

Is there a way to switch tabs with foundation 5 Joyride?
I have foundation tabs on the page and want Joyride to point elements on different tabs.
Like mentioned in the comment from Steven, you could use the callback either in the pre or post step callback function you activate the tab you need.
post_step_callback : function (){}, // A method to call after each step
pre_step_callback : function (){} // A method to call before each step
Hope this helps...
Here's what worked for me. I looked around and couldn't find anything useful, so wrote this. The hardest part was figuring out how to get the id of the target anchor. This was found buried in the 'this' object available to the callback.
$(this.$target)[0].id;
The 'content' class is used by foundation to identify the content to display when a tab is clicked. So traversing up the .parents tree finding the enclosing elements gives you the content tab(s) holding your link. And then of course you have to add an id to the <a> element of the tab you want to click. If you name it the same as your content div, with '-a' appended, you should be good to go.
html:
<dl class="tabs radius" data-tab id="my_tabs">
<dd class="active">Tab 1</dd>
<dd class="active">Tab 2</dd>
</dl>
<div class="tabs-content">
<div class="content" id="tab1">
<article id="joyride_stop1">...</article>
</div>
<div class="content" id="tab2">
<article id="joyride_stop2">...</article>
</div>
</div>
js:
$(document).ready(function() {
$(document).foundation('joyride', 'start', {
pre_step_callback: function(i, tip) {
var target = $(this.$target)[0].id;
if($('#' + target).parents('.content').length > 0) {
$('#' + target).parents('.content').each(function() {
var id = $(this).attr('id');
if($('#' + id).is(':visible') == false) {
$('#' + id + '-a').click();
}
});
}
}
});
});
This will work on any page, whether it contains tabs or not, so it can be universally included across a site.

How to access html value of property that triggers an event in Meteor?

If I have a list of items in my template, like this:
<template name="myTemplate">
<ul>
<li>One</li>
<li>Two</li>
<li>Three</li>
</ul>
</template>
And my event handler looks something like this:
Template.myTemplate.events({
'click li': function(event) {
console.log(event.currentTarget//.? .html, .value?
}
});
How would I access the value of the li item that was clicked? i.e. I want to access 'One' or 'Two', etc. I tried .html and .value, which would have been the jquery-esque way to do it. My understanding is using 'currentTarget' is correct, since 'target' should match all li's, but I don't know how to hone in on the html value.
.innerHTML is the answer.
console.log(event.currentTarget.innerHTML); // Outputs li HTML content
As anonymous say. use the native attribute innerHTML to get the content of a DOM element.
otherwise Meteor come with JQuery so you can use it like this
console.log($(event.currentTarget).html());
You can try this :
Template.myTemplate.events({
'click li': function(event) {
$(event.target).html()
//console.log(event.currentTarget//.? .html, .value?
}
});

How to perform click event on an element present in the anchor tag?

<div class="buttonClear_bottomRight">
<div class="buttonBlueOnWhite">
<a onclick="$find('{0}').close(true); callPostBackFromAlert();" href="#">Ok</a><div
class='rightImg'>
</div>
</div>
</div>
In the above code i wanted to click on Ok button present in the anchor tag.But an id is not generated because of which i cannot directly perform a click action. I tried a work around mentioned below.
IElementContainer elm_container = (IElementContainer)pw.Element(Find.ByClass(classname));
foreach (Element element in elm_container.Elements)
{
if (element.TagName.ToString().ToUpper() == "A")
{
element.Click();
}
}
But here elm_container returns null for intial instances due to which we cannot traverse through it. Is there any other easy method to do it ?
Try this...
Div div = browser.Div(Find.ByClass("buttonClear_bottomRight")).Div(Find.ByClass("buttonBlueOnWhite"));
Debug.Assert(div.Exists);
Link link = div.Link(lnk => lnk.GetAttributeValue("onclick").ToLower().Contains(".close(true)"));
Debug.Assert(link.Exists);
link.Click();
Hope it helps!
You can simply Click on the link by finding its text
var OkButton = Browser.Link(Find.ByText("Ok"));
if(!OkButton.Exists)
{
\\Log error here
}
OkButton.Click();
Browser.WaitForCompplete();
Or you can find the div containing the link like,
var ContainerDiv = Browser.Div(Find.ByClass("buttonBlueOnWhite"));
if(!ContainerDiv.Exists)
{
\\Log error here
}
ContainerDiv.Links.First().Click();
Browser.WaitForComplete();

Resources