Skip to content
This repository has been archived by the owner on Sep 12, 2022. It is now read-only.

how to apply if and OR if or condition in td tag in html file in geb spock report #9

Closed
durgeshshisode1988 opened this issue May 14, 2018 · 10 comments
Labels

Comments

@durgeshshisode1988
Copy link

Hi @tilmanginzel

I am using athaydes reports for my geb spock html report. I am trying to modify the html report to get the status of the test case. For that I have added new column as 'Final Column' Below is html I am using:

<table class="summary-table">
    <thead>
    <tr>
        <th>Name</th>
        <th>Features</th>
        <th>Failed</th>
        <th>Errors</th>
        <th>Skipped</th>
        <th>Time</th>
        <th>Final Status</th>
    </tr>
    </thead>
    <tbody>
    <% data.each { name, map ->
    def s = map.stats%>
    <tr class="${s.errors ? 'error' : ''} ${s.failures ? 'failure' : ''} ">
        <td><a href="${name}.html">$name</a></td>
        <td>${s.totalRuns}</td>
        <td>${s.failures}</td>
        <td>${s.errors}</td>
        <td>${s.skipped}</td>
        <td>${fmt.toTimeDuration(s.time)}</td>
        <td if="${s.totalRuns} != 0" ? 'PASS' : 'FAILED >${s.totalRuns = 0 ? 'PASS' : 'FAILED' }</td>
    </tr>
    <% } %>
    </tbody>
</table>
<table class="summary-table">
    <thead>
    <tr>
        <th>Name</th>
        <th>Features</th>
        <th>Failed</th>
        <th>Errors</th>
        <th>Skipped</th>
        <th>Time</th>
        <th>Final Status</th>
    </tr>
    </thead>
    <tbody>
    <% data.each { name, map ->
    def s = map.stats%>
    <tr class="${s.errors ? 'error' : ''} ${s.failures ? 'failure' : ''} ">
        <td><a href="${name}.html">$name</a></td>
        <td>${s.totalRuns}</td>
        <td>${s.failures}</td>
        <td>${s.errors}</td>
        <td>${s.skipped}</td>
        <td>${fmt.toTimeDuration(s.time)}</td>
        <td if="${s.totalRuns} != 0" ? 'PASS' : 'FAILED >${s.totalRuns = 0 ? 'PASS' : 'FAILED' }</td>
    </tr>
    <% } %>
    </tbody>
</table>

Now my requirement is that if "${s.failures}" and "${s.errors}" and "${s.skipped}" are equal to zero, then only the value for column should come as "PASS" else it should be "FAILED".

I tried something like <td if="${s.totalRuns} != 0" ? 'PASS' : 'FAILED >${s.totalRuns = 0 ? 'PASS' : 'FAILED' } however this solution is not working as I am very new to html and also not able to understand the syntax of it correctly

Can you please help me on this front. Thanks!

I have created below stack overflow issue for this as well:
https://stackoverflow.com/questions/50295732/how-to-apply-if-and-or-if-or-condition-in-td-tag-in-html-file

Please help me. Thanks!

@tilmanginzel
Copy link
Contributor

tilmanginzel commented May 14, 2018

Hey @durgeshshisode1988,

You can use the following code snippet, to show FAILED if failures, errors or skipped tests occured, and PASS if not. I am not sure though if skipped tests should result in a FAILED:

<td>${ s.failures || s.errors || s.skipped ? 'FAILED' : 'PASS' }</td>

As s.failures and the rest are integers, we don't need to explicitly check if they are more than 0.

If you do also want to hide the value if s.totalRuns is zero, you could add another condition. General rule of thumb: Everything between <% ... %> can be any Groovy code. There might be cleaner solutions than this one, but it does the trick:

<td>
    <% if (s.totalRuns) { %>
        ${ s.failures || s.errors || s.skipped ? 'FAILED' : 'PASS' }
    <% } %>
</td>

Furthermore, I don't think that <td if="..."> is valid syntax. The templates use the GStringTemplateEngine, which is based on the SimpleTemplateEngine. Here is a short documentation: http://docs.groovy-lang.org/next/html/documentation/template-engines.html

Hope that helps! :)

@durgeshshisode1988
Copy link
Author

durgeshshisode1988 commented May 15, 2018

Hi Tilman,

Your first solution is working absolutely fine.
With the second solution I am getting partial correct results. I have attached the screenshot for the same.
reports

Thanks for the documentation, as I was struggling a bit to get the correct information.
Furthermore I am planning to add the drop-down for Final-status column to male the filtering easy based on status of the test case. If possible can you please help me to get the drop down at column level for final staus

I am very thankful of your quick help on my questions.

Regards,

Durgesh

@tilmanginzel
Copy link
Contributor

tilmanginzel commented May 15, 2018

Hi,

unfortunately I don't know why s.totalRuns is zero in the first two rows (as seen in the Features column). I would probably ignore the if altogether and simply use something like this:

<td>${ s.failures || s.errors ? 'FAILED' : 'PASS' }</td>

I assume it is an edge case that zero tests have been executed, therefore it's ok to show PASS in my opinion.

You could check out the following articles regarding the filtering, which do not require JavaScript:
https://nddt-webdevelopment.de/html-css/filter-html-table-without-javascript-just-css or
https://stackoverflow.com/a/7383306/5115653

I can also try to help with that in the following days, but I don't have the time today.

@durgeshshisode1988
Copy link
Author

Hi Tilman, Thanks for your support and help. Will refer those documents. Also your help is appreciated for making this possible. During office hours not able to send you the message, so delaying response.

Thanks,
Durgesh

@tilmanginzel
Copy link
Contributor

Hey,

I created a working example. I used a few radio buttons (disguised as normal buttons) and placed it above the table.

Result:

filter-table

There are basically two required parts: CSS for styling and filter logic, and a bit of HTML. Here is the CSS with some comments:

<head>
...
    <style>
        /* by default, hide all table rows */
        .filtered-table tbody tr { display: none; }

        /* let's also hide the radio buttons */
        .table-filter { display: none }

        /* label for the radio button which will apply the filter */
        .table-filter + label {
            display: inline-block;
            cursor: pointer;
            color: #000;
            padding: 5px;
            margin: 2px;
            font-size: 12px;
            border: 1px solid lightblue;
            opacity: 0.4;
        }

        /* increase the opacity of the label if it is checked */
        .table-filter:checked + label{
            opacity: 1.0;
        }

        /* if a radio button is :checked, display the relevant table row */
        #show-failed.table-filter:checked ~ table tbody tr.show-FAILED,
        #show-pass.table-filter:checked ~ table tbody tr.show-PASS,
        #show-all.table-filter:checked ~ table tbody tr {
            display: table-row;
        }

        /* just a text label, not required */
        .filter-label {
            margin-left: 6px;
            font-size: 12px;
        }
    </style>
</head>

Now we just need some radio buttons to apply the filter logic. These are placed right before the <table> together with some labels. Also note that I saved the FAILED/PASS value in variable called finalStatus. This is used to add a CSS-class called show-FAILED or show-PASS, which will be used to filter the respective rows:

...
<h3>Specifications</h3>

<span class="filter-label">Filter table:</span>
<input type="radio" class="table-filter" name="filter-group" id="show-all" checked />
<label for="show-all">ALL</label>

<input type="radio" class="table-filter" name="filter-group" id="show-failed" />
<label for="show-failed">FAILED</label>

<input type="radio" class="table-filter" name="filter-group" id="show-pass" />
<label for="show-pass">PASS</label>

<table class="summary-table filtered-table">
    <thead>
    <tr>
        <th>Name</th>
        <th>Features</th>
        <th>Failed</th>
        <th>Errors</th>
        <th>Skipped</th>
        <th>Success rate</th>
        <th>Time</th>
        <th>Final Status</th>
    </tr>
    </thead>
    <tbody>
    <% data.each { name, map ->
    def s = map.stats
    def finalStatus = s.failures || s.errors || s.skipped ? 'FAILED' : 'PASS'
    %>
    <tr class="${s.errors ? 'error' : ''} ${s.failures ? 'failure' : ''} show-${finalStatus}">
        <td><a href="${name}.html">$name</a></td>
        <td>${s.totalRuns}</td>
        <td>${s.failures}</td>
        <td>${s.errors}</td>
        <td>${s.skipped}</td>
        <td>${fmt.toPercentage(s.successRate)}</td>
        <td>${fmt.toTimeDuration(s.time)}</td>
        <td>${finalStatus}</td>
    </tr>
    <% } %>
    </tbody>
</table>
...

I mostly followed this tutorial with some minor adjustments: https://nddt-webdevelopment.de/html-css/filter-html-table-without-javascript-just-css

One caveat: The CSS-only solution requires us to place the radio buttons directly before the table. We cannot nest it any deeper. I suppose a dropdown is also possible by using <select>.

I hope everything makes sense. :) Feel free to make some adjustments which will fit your needs!

Cheers :)

@durgeshshisode1988
Copy link
Author

Hi Tilman,

This is working fantastic. It's exactly I wanted. Thanks so much for your help.
Small question. When the test case is completely failed then also the success rate is 100% and text is in red color. Initially it was quite confusing because test case is failed then the success rate should be 0%.

Thanks,
Durgesh

@tilmanginzel
Copy link
Contributor

tilmanginzel commented May 19, 2018

Hi,

good question. Unfortunately I don't know and cannot reproduce it. All the values are provided by the spock-reports library, so I don't have much influence on it. This library basically only provides a new report template which adds screenshots taken by Geb.

I am gonna close this issue for now. If you have any other questions, feel free to ask!

@durgeshshisode1988
Copy link
Author

Hi Tilman,
NP, Thanks for your help on this.

@subbu3397
Copy link

Hi tilmanginzel,
I need the same solution as you have done above and I don't know how to override that existing HTML file with the modified one. can you help me out?

@tilmanginzel
Copy link
Contributor

Hey @subbu3397, this solution has been added to the library by now. I have not yet published a new version, but I hopefully can do so in the coming week. In the meantime, you could checkout from master and build the library for yourself.

Regarding your question on how to modify the template: This library is basically an example for that, as it's overwriting the templates from spock-reports. ;)

These are the necessary steps:

  • Add your custom template to /src/test/resources
  • Specify your template in src/test/resources/META-INF/services/com.athaydes.spockframework.report.IReportCreator.properties, as shown here

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

3 participants