Jenkins pipeline script to send customized email - jenkins

I've been trying to use my customized content for the Jenkins build emails. I got stuck when I am trying to change the contents of html dynamically based on the results from previous stages. I am passing the contents of an html to a variable as below and when i try to access the hash list in that, the value of arrays(key and value of an array) are not getting printed.
def content = """\
<html>
<head>
<style>
</style>
</head>
<body>
<table style=" background-color:lightgreen; width:900px;margin:0;">
<tr>
<th>Build Results :</th>
</tr>
<tr>
<td>project Name : </td>
<td>project URL : </td>
</tr>
<tr>
<td>Build Number : ${var3} </td>
</tr>
<tr>
<td>Buid URL :</td>
</tr>
</table>
<table style=" background-color:lightblue; width:900px;margin:0;">
<tr>
<% stagearray.each { item ->
def key=item.key;
def value=item.value; %>
<td>${key}</td>
<td>${value}</td>
<% } %>
</tr>
this is the sample
<tr><td>This is test line </td></tr>
</table>
</body>
</html>
"""
Any help would be highly appreciated.

Related

When do you use th:remove="tag" versus th:block?

The following two blocks would evaluate the same, so when would you use th:remove="tag" over th:block?
<th:block th:text="${myBean.value}">[value]</th:block>
versus
<span th:remove="tag" th:text="${myBean.value}">[value]</span>
Since they can be used interchangeably I think it is opinion based... but for readability, my opinion is:
<th:block /> should be used for doing structural logic (th:if, th:each, etc..) and only when it's not possible on the parent tag. For example, in the case you have to contain more than one element in a loop -- e.g, a loop that produces 2 table rows for each object:
<table>
<th:block th:each="object: ${objects}">
<tr>
<td th:text="${object.data1}" />
<td th:text="${object.data2}" />
</tr>
<tr>
<td th:text="${object.data3}" />
<td th:text="${object.data4}" />
</tr>
</th:block>
<table>
th:remove should only be used for example data that should only be rendered when viewing the file in a browser/prototyping w/o rendering the thymeleaf:
<table>
<th:block th:each="object: ${objects}">
<tr>
<td th:text="${object.data1}" />
<td th:text="${object.data2}" />
</tr>
<tr>
<td th:text="${object.data3}" />
<td th:text="${object.data4}" />
</tr>
</th:block>
<tr th:remove="all">
<td>Mild Cinnamon</td>
<td>1.99</td>
</tr>
<tr th:remove="all">
<td>Other</td>
<td>Data</td>
</tr>
<table>
In the specific case where you want to output data/text without a tag, I prefer inline expressions. They're enabled by default in thymeleaf 3. So:
[[${myBean.value}]] instead of <th:block th:text="${myBean.value}">[value]</th:block>

How to apply if condition in table td in thymeleaf

I am new to thymeleaf, I have a little problem. I am successfully getting data from database and displaying to table formate, here i am getting true/false from database. Same thing displaying in table formate.
But i want to show true as yes and fasle as no in front end.
<tbody>
<tr th:each="trn,iterStat : ${trans}">
<td th:text="${trn.txn}">Yes</td>
</tr>
</tbody>
How to change my code?
Different ways to go about this depending on what you want your html to look like:
<tbody>
<tr th:each="trn,iterStat : ${trans}">
<td th:text="${trn.txn ? 'Yes' : 'No'}" />
</tr>
</tbody>
or
<tbody>
<tr th:each="trn,iterStat : ${trans}">
<td>
<span th:if="${trn.txn}">Yes</span>
<span th:unless="${trn.txn}">No</span>
</td>
</tr>
</tbody>

How to verify the initial text using geb

I am using geb spoke. For the below html structure I am not able to get the text from specified location:
Below is the html structure:
<div class="tab-pane ng-scope active" uib-tab-content-transclude="tab" ng-class="{active: tab.active}" ng-repeat="tab in tabs">
<div id="algemeen-tab-header" class="ng-tab-hdr ng-scope"></div>
<div id="algemeen-tab-body" class="ng-tab-bdy table-view ng-scope">
<table class="ng-tbl valign-top">
<tbody class="esuite-table-body">
<tr>
<td class="tp-label">
<label class="ng-binding">
Reference:
</label>
</td>
<td class="tp-field ng-binding">
I-5006-2015
</td>
<td class="tp-label ng-hide" ng-show="!zaak.anoniem"></td>
<td class="tp-field ng-binding ng-hide" ng-show="!zaak.anoniem"></td>
<td class="tp-label" ng-show="zaak.anoniem"></td>
<td class="tp-field ng-binding" ng-show="zaak.anoniem"></td>
<td class="tp-label"></td>
<td class="tp-field ng-binding"></td>
</tr>
<tr></tr>
<tr></tr>
<tr></tr>
<tr></tr>
<tr></tr>
<tr></tr>
<tr></tr>
</tbody>
</table>
</div>
</div>
I wanted to verify the text "I-5006-2015". I am not able to do it. Also, second scenario is that, I just wanted to assert that initial word is "I" from that location. How I can do that.
I have tried below variable to get the location but got failed:
referenceNumberText(wait:true){$("td", class: contains("tp-field ng-binding"))}
Please help me on this. Thanks!
Since you use html ids rather rarely, the selector for you text would be:
$("#algemeen-tab-body > table > tbody > tr:nth-child(1) > td:nth-child(2)").text()
Did you consider naming <td>'s? Example:
<td id="referenceNumber" class="tp-field ng-binding">
I-5006-2015
</td>
So your selector would be as easy as $("#referenceNumber").text()...

Limit search scope of XPath in Nokogiri

I would like to find specific tags within a Node which is in a NodeSet but when I used XPath it returns results from the whole NodeSet.
I'm trying to get something like:
{ "head1" => "Volume 1", "head2" => "Volume 2" }
from this HTML:
<h2 class="header">
<a class="header" >head1</a>
</h2>
<table class="volume_description_header" cellspacing="0">
<tbody>
<tr>
<td class="left">Volume 1</td>
</tr>
</tbody>
</table>
<h2 class="header">
<a class="header" >head2</a>
</h2>
<table class="volume_description_header" cellspacing="0">
<tbody>
<tr>
<td class="left">Volume 2</td>
</tr>
</tbody>
</table>
So far I've tried:
require 'nokogiri'
a = File.open("code-above.html") { |f| Nokogiri::HTML(f) }
h = a.xpath('//h2[#class="header"]')
puts h.map { |e| e.next.next }[0].xpath('//td[#class="left"]')
But with this I get:
<td class="left ">Volume 1</td>
<td class="left ">Volume 2</td>
I'm expecting only the first one.
I've tried doing the XPath inside the block but this gives me the the same result twice.
I checked and
puts h.map { |e| e.next.next }[0]
evaluates to the first Node so I don't understand why XPath looks in the whole NodeSet or even the whole Nokogiri::Document, as I think that's what it actually does.
Can somebody please explain me the principles of searching and navigating within a selected Node/NodeSet, not the whole Document? Maybe navigating down a known path would be better in this case but I don't know how to do that either.
Your second XPath expression, //td[#class="left"], starts with //. This means to start at the root of the entire document when matching nodes. What you want is to start from the current node. To do that start your expression with a dot .//:
d.xpath('.//td[#class="left"]')

want to parse href in ruby on rails using nokogiri

I am using nokogiri as my HTML parser.
<html>
<body>
<form>
<table>
<tr><td>Some Text</td></tr>
<tr>
<td colspan="2" align="center">
<br />
<a href="TransportRoom?servlet=CaseSearch.jsp&advancedSearch=Advanced">
Advanced Search
</a>
<br />
</td>
</tr>
</table>
</form>
</body>
</html>
In this html code I want to parse the "Advance Search" link. This html is saved in variable named doc1
Can anyone help me with this?
Should be as simple as
doc = Nokogiri::HTML(doc1)
href = doc.css("a").first.attr('href')
This is what you want?
First answer is working for me but if there is n number of links than we can manipulate it by this way
html = Nokogiri::HTML(doc1)
html.css("a").each do |element|
if (element.text.strip == 'Advanced Search')
advance_search_link = element.attr('href')
end
end
I would do as below :
require 'nokogiri'
#doc = Nokogiri.HTML <<-eotl
<html>
<body>
<form>
<table>
<tr><td>Some Text</td></tr>
<tr>
<td colspan="2" align="center">
<br />
<a href="TransportRoom?servlet=CaseSearch.jsp&advancedSearch=Advanced">
Advanced Search
</a>
<br />
</td>
</tr>
</table>
</form>
</body>
</html>
eotl
#doc.at_xpath("//a[normalize-space(.)='Advanced Search']")['href']
# => "TransportRoom?servlet=CaseSearch.jsp&advancedSearch=Advanced"

Resources