How to target sibling DIV node in XPath - xpath

I have this html code:
<div class="info">
<div class="label">Phone</div>
<div class="text">+966 (13) 828 3771</div>
</div>
Using XPath, I need to target the Text inside div class text.
For now, I'm using this code and I can target the div class label:
.//*[#class="label"]/text()[contains(.,"Phone")]
How could I target the text inside <div class="text">?
There are other <div class="info"> and <div class="label">, and I need to target those that are direct sibling of <div class="label"> that contains Phone in it.

//div[#class = 'info' and div[#class = 'label' and contains(., 'Phone')]]/div[#class = 'text'] should select the div element(s) with the class attribute text inside a div parent element that has the class attribute info and a child div with class as label and which contains the text Phone.

Related

How to select an svg element with title using cypress?

i want to hover on a svg element inside div element with class main. this svg element has title tag "Header element"
below is the code
<div class="main">
<div class="box">
<div class="cell"></div>
<div class="cell"></div>
<div class="cell">
<div>
<svg></svg>
<span> //want to hover on this element
<svg>
<title>Header element</title>
</svg>
</span>
</div>
</div>
</div>
</div>
as seen from code above, i want to hover on span element that contains svg with title Header element.
i have tried using below
cy.get(`.main>div`)
.contains('svg', 'Header element')
.trigger('mouseover')
but this is not working
could someone help me locating this span element using cypress. thanks.
You are selecting the svg but want to hover the span, so add a parent selector
cy.get(`.main>div`)
.contains('svg', 'Header element')
.parent('span')
.trigger('mouseover')
I think you are missing . (class selector)
cy.get(`.main>div`)
.contains('svg', 'Header element')
.triggers('mouseover')

XPath - exclude descendants of specific selector

I have following markup (schema.org attributes included):
<body>
<div itemscope itemtype="http://schema.org/Foo">
<div>
<div itemname="name">
Foo scoped name
</div>
</div>
<div>
<div itemscope itemtype="http://schema.org/Bar">
<div>
<div itemname="name">
Bar scoped name
</div>
</div>
</div>
</div>
</div>
</body>
I need to select (presumably by xpath as css selectors won't be enough for the task) divs that have itemname="name" in http://schema.org/Foo scope but not those that have another element with itemscope attribute ascending them.
So in example provided I need to select only "Foo scoped name", but not "Bar scoped name".
You can use something like :
//div[#itemname="name"][ancestor::div[#itemscope][1][#itemtype="http://schema.org/Foo"]]
Look for a div element with a specific attribute value (#itemname="name"). Its first div ancestor (with #itemscope attribute) contains also a specific #itemtype attribute value (http://schema.org/Foo).
Output : <div itemname="name"> Foo scoped name </div>

XPATH: Select a node whose children do not containg some text

I'm trying to select a node whose children do not contain some specific text.
For example:
<div class="b-margin">
<div class="tag">Pt</div>
<div class="tag">En</div>
</div>
<div class="b-margin">
<div class="tag">Ru</div>
<div class="tag">En</div>
</div>
How would i go about selecting the 'div class="b-margin"' nodes that do not have children with the text "Pt"?
Here is the simple xpath.
//div[#class='b-margin' and not(div[.='Pt'])]
Screenshot:

jsPlumb multiple containment drag parent

I have following HTML
<div class='wraper'>
<div class="demo statemachine-demo1">
<div class="w" id="inperson">IN PERSON
<div class="ep"></div>
</div>
<div class="w" id="rejected">
REJECTED
<div class="ep"></div>
</div>
</div>
<div class="demo statemachine-demo1">
<div class="w" id="inperson">IN PERSON
<div class="ep"></div>
</div>
<div class="w" id="rejected">
REJECTED
<div class="ep"></div>
</div>
</div>
</div>as per the above HTML the wrapper div contains two div each .demo div contains two div and are connected to each other .statemachine-demo1 .inperson div to .statemachine-demo2 .inperson(.statemachine-demo1.inperson ----> .statemachine-demo2.inperson) and .statemachine-demo1 .reject to .statemachine-demo2 .reject(.statemachine-demo1.reject -----> .statemachine-demo2.reject).
now if i drag class w the join line will move continuously, but what i want to know is their any way if i drag parent div statemachine-demo1 the child div reject and inperson class div should also move along with joined line continuously.
For this you need customised jquery draggable function instead of using jsPlumb.draggable() for parent div's. Whenever you drag a parent div, you need to check whether any of the child has connection, if so you need to repaint those connections. Code:
$('.demo').draggable({ // considering parent div has 'demo' class as in your case
drag:function(event){
// on drag check any child has connections and repaint them
$(this).find('._jsPlumb_endpoint_anchor_').each(function(i,el){
jsPlumb.repaint($(el));
});
}
});

nokogiri + mechanize css selector by text

I am new to nokogiri and so far most familiar with CSS selectors, I am trying to parse information from a table, below is a sample of the table and the code I'm using, I'm stuck on the appropriate if statement, as it seems to return the whole contents of the table.
Table:
<div class="holder">
<div class ="row">
<div class="c1">
<!-- Content I Don't need -->
</div>
<div class="c2">
<span class="data">
<!-- Content I Don't Need -->
<span class="data">
</div>
</div>
...
<div class="row">
<div class="c1">
SPECIFIC TEXT
</div>
<div class="c2">
<span class="data">
What I want
</span>
</div>
</div>
</div>
My Script: (if SPECIFIC TEXT is found in the table it returns every "div.c2 span.data" variable - so I've either screwed up my knowledge of do loops or if statements)
data = []
page.agent.get(url)
page.search('div.row').each do |row_data|
if (row_data.search('div.c1:contains("/SPECIFIC TEXT/")').text.strip
temp = row_data.search('div.c2 span.data').text.strip
data << temp
end
end
There's no need to stop and insert ruby logic when you can extract what you need in a single CSS selector.
data = page.search('div.row > div.c1:contains("SPECIFIC TEXT") + div.c2 span.data')
This will include only those that match the selector (e.g. follow the SPECIFIC TEXT).
Here's where your logic may have gone wrong:
This code
if (row_data.search('div.c1:contains("SPECIFIC TEXT")'...
temp = row_data.search('div.c2 span.data')...
first searches the row for the specific text, then if it matches, returns ALL rows matching the second query, which has the same starting point. The key is the + in the CSS selector above which will return elements immediately following (e.g. the next sibling element). I'm making an assumption, of course, that the next element is always what you want.
I'd do
require 'nokogiri'
html = <<_
<div class="holder">
<div class ="row">
<div class="c1">
<!-- Content I Don't need -->
</div>
<div class="c2">
<span class="data">
<!-- Content I Don't Need -->
<span class="data">
</div>
</div>
<div class="row">
<div class="c1">
SPECIFIC TEXT
</div>
<div class="c2">
<span class="data">
What I want
</span>
</div>
</div>
</div>
_
doc = Nokogiri::HTML(html)
css_string = 'div.row > div.c1[text()*="SPECIFIC TEXT"] + div.c2 span.data'
doc.at(css_string).text.strip
# => "What I want"
How those selectors would work here -
[name*="value"] - Selects elements that have the specified attribute with a value containing the a given substring.
Child Selector (“parent > child”) - Selects all direct child elements specified by "child" of elements specified by "parent".
Next Adjacent Selector (“prev + next”) - Selects all next elements matching "next" that are immediately preceded by a sibling "prev".
Class Selector (“.class”) - Selects all elements with the given class.
Descendant Selector (“ancestor descendant”) - Selects all elements that are descendants of a given ancestor.

Resources