Xpath up to parent element using nightwatch - css

I have this structure:
<div class="class">
<h4 class="class2">
"Condition" </h4>
<div class = "click_class">Click_text </div>
</div>
I heed to click on the element with class ="click_class" if the h4 text == "Condition".
I try Xpath:
.useXpath()
.click('//div[contains(#class, "class")]//h4[text()[contains(.,"Condition")]
It is works. I found the h4 with text == "Condition". Now, in my opinion, I need to go to parent class and click on click_class.
.click('//div[contains(#class, "class")]//h4[text()[contains(.,"Condition")]..//div[text()="Click_text"]')
but it is not works.
How can I click on the element with text with condition in h4?

Try below XPath:
//h4[normalize-space(text())="Condition"]/following-sibling::div[#class="click_class"]

Alternatively, you can put the expression that check for text content of h4 in a predicate for the parent div instead :
//div[contains(#class, "class")][h4/text()[contains(.,"Condition")]]
and then navigate to return child div element that have class "click_class" :
/div[contains(#class, "click_class")]
So the entire expression would be as follows (wrapped for readability) :
//div[contains(#class, "class")][h4/text()[contains(.,"Condition")]]
/div[contains(#class, "click_class")]
demo

Related

Xpath in Nightwatch.js

I have this structure
<div class ="wg-block">
...
<h4 class ="number" >
"Text"
I have to make sure that the element h4 with text "text" is in div.
I try this:
.useXpath()
.waitForElementVisible('/div[contains(#class, "wg-block")]/h4[text()="Text"]',1000)
but have an error.
How can I correctly be sure in visibility of this element?
Try to replace
'/div[contains(#class, "wg-block")]/h4[text()="Text"]'
with
'//div[#class = "wg-block"]//h4[normalize-space(text())="Text"]'
Note that starting / applicable for root element (which is html, but not div) and also / means direct child. So /div/h4 means h4 which is the direct child of a root element div.
You should use //div//h4 to match h4 which is descendant of div that is located somewhere in DOM
text()="Text" could be applied to match element <h4>Text</h4>,
but if you want to match
<h4>
Text
</h4>
you need to get rid of spaces and new line characters. In this case you can use normalize-space(text()) method or contains(text(), "Text")

Selecting child of adjacent sibling

For markup such as:
<span class="location-title-container">
</span>
<div class="content-panel">
<div class="floor-left-panel"></div>
<div class="floor-right-panel"></div>
</div>
How do I select .floor-left-panel when hovering over .location-title-container?
You have to use a adjacent selector to get the element right after it.
Your selector would look like this:
.location-title-container:hover + .content-panel .floor-left-panel { … }
Just for your information, you should not use :hover on span tags.
They are not accessible by default. You should add some WAI ARIA role tags.
.location-title-container:hover + .content-panel .floor-left-panel {} is the selector you need.
The plus sign is used to select the next adjacent element in the DOM.

Select element based on previous element of same type

I'm trying to select elements based on the class of a previous element of the same type.
For example, given the following HTML, select the third span element:
<div>
<span class="red"></span>
<span class="red"></span>
<p>
<span id="select me"></span>
</p>
<span id="don't select me"></span>
</div>
I want that span element to have the same properties as the previous span element because it has the class, "red."
Another way to say this: select an element with the class, "red," as well as the next element of the same type, regardless of class.
I'm having a tough time wrapping my head around this. Better than nothing would be a way to select the next sibling of the same type instead of just any following element. For example, span.red ~ span would be okay if it didn't mean "span element with ANY previous span sibling with a class red."
Thanks for any help.
Here are more examples:
<div>
<span class="red"></span>
<span id="select me"></span>
<p>
<span class="red"></span>
</p>
<span id="select me"></span>
</div>
In the example above, the second span element is chosen because the first span has a class, "red."
The last span element is chosen because the third span has a class, "red."
<div>
<span class="red"></span>
<span class="red"></span>
<p>
<b></b>
</p>
<span id="select me"></span>
</div>
The main reason for this is that I have elements in an editable div. They are numbered with a css counter. Some elements may be grouped together like a figure, i.e. 2a and 2b, while others are not, so I could end up with elements 1, 2a, 2b, 2c, 3, etc. The class name I use just tells me that it's a "sub" element and to increment the sub counter but not the main element counter. Not having a class for the next element after a bunch of sub elements tells me it's the last sub element and I should reset the sub counter. The reason I have it set up this way is because I want to be able to move around the elements and have the numbering update automatically. Also, it's easy to change whether something is a sub element just by toggling the class name.
I'd like to have another case or two to test this with, but this seems to work for your example:
span.red ~* span {
background: red;
}
jsFiddle example
There's no way to say "sibling of the same type" in a selector. But you can use the sibling selector following a selector of your choice, and combine these into a single selector that meets your needs, such as:
span.red + span, div.red + div
{
}
If it's only nested on level you could try this :
.red + * > span {
color: red;
}
What is the use case for this? Why not just add red to all elements you want to be styled the same way?

Div tag displaying content in new line

I have code that looks like this:
<h4 class="tableTotals">Total Selected: R<div id="bankTotal">##,##</div></h4>
The output that I want should all be in ONE line but as it turns out the div tags displays it's content in a new line, which I don't exactly want. So the output looks like this:
Total Selected: R
##,##
When I actually want it to display like this:
Total Selected: R##,##
Does anybody know how to stop the div displaying on a new line?
Thank for any push in the right direction!
Use <span> instead of <div>
div is a block element, and h4 is a header meant for single line.
Style your div to be displayed as inline-block
#bankTotal { display: inline-block; }
Demo
Using inline-block does not have to chang the div completely into as inline element just like span . Furthermore, you can still have block properties.
<div> is a block element and will put a return before and after the <div>
You should use instead.
<h4 class="tableTotals">Total Selected: R<span id="bankTotal">##,##</span></h4>
Using CSS:
#bankTotal{
display:inline;
}
div displaying on a new line ?
<div id="bankTotal" style="display:inline">##,##</div>
or
<div id="bankTotal" style="float:left">##,##</div>
but better :
<span id="bankTotal" >##,##</span >
display:inline property of css for displaying the div "inline",
or u could use <span> tag instead of <div> tag ..
<h4 class="tableTotals" style="display:inline;">Total Selected: R<div id="bankTotal" style="float:left;">##,##</div></h4>
Here I have added a style to position the DIV manually to where you want it to be. Please note that I didn't put it in its exact position so just fiddle with the margin PX.
<h4 class="tableTotals">Total Selected: R<div id="bankTotal" style="margin-left:50px;margin-top:-10px;">##,##</div></h4>

What does the CSS “.x-data .x-time span” mean?

What does the following CSS syntax mean?
.x-data .x-time span
it is a selector for a span that resides in a div (or anything) with class .x-time, which inturn is nested inside a class .x-data
for example, if you had the css like:
.x-data .x-time span {
font-size: 12px;
color: red;
}
and then a structure like this:
<div class="x-data">
<div class="x-time">
Time: <span>12:00</span>
</div>
</div>
then the 12:00 is going to be in font size 12, and in red. where as "Time:" part is just going to follow the inherited format.
It targets the span elements inside elements with class "x-time", which, themselves, are also inside element with class="x-data".
Selects any span element that is a descendant of any element with a class attribute that contains the word x-time that is a descendant of any element with a class attribute that contains the word x-data.
via SelectOracle. I recommend giving Selectutorial a read too.
its like saying Donkey's Tail's Hair.
so .x-data will be donkey
.x-time will be tail
span will be hair!!
so .x-data's .x-time's span.
get it?
any element with a class of '.x-data' containing any element with a class of '.x-time' containing any <span> will be styled.
eg.
<p class="x-data">
lipsum
<span class="x-time">
<span>lipsum</span> <!-- only this guy is styled -->
<strong>sdadsa</strong>
</span>
<span>dolor</span>
</p>

Resources