Skip to content
This repository has been archived by the owner on May 1, 2024. It is now read-only.

Commit

Permalink
feat(Report): support linking to an individual feature or scenario (#64)
Browse files Browse the repository at this point in the history
Co-authored-by: jkuester <[email protected]>
  • Loading branch information
jkuester and jkuester authored Jan 3, 2021
1 parent d314eac commit 6925967
Show file tree
Hide file tree
Showing 7 changed files with 112 additions and 20 deletions.
18 changes: 18 additions & 0 deletions features/support/usageSteps.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,24 @@ When('the box is checked to show tags', function () {
this.outputHTML.getElementById('tagsCheckbox').click();
});

When(/^the report is opened with a link for the (first|second) feature title$/, function (featureIndex) {
const index = featureIndex === 'first' ? 0 : 1;
const featureWrappers = this.outputHTML.getElementsByClassName('feature-wrapper');
const featureAnchor = featureWrappers[index].getElementsByClassName('anchor')[0];

this.createWindow(`https://localhost/#${featureAnchor.id}`);
});

When(/^the report is opened with a link for the (first|second) scenario title in the (first|second) feature$/, function (scenarioIndex, featureIndex) {
const fIndex = featureIndex === 'first' ? 0 : 1;
const featureWrappers = this.outputHTML.getElementsByClassName('feature-wrapper');
const sIndex = scenarioIndex === 'first' ? 0 : 1;
const scenarioAnchors = Array.from(featureWrappers[fIndex].getElementsByClassName('anchor'))
.filter((anchor) => anchor.hasAttribute('scenario-button'));

this.createWindow(`https://localhost/#${scenarioAnchors[sIndex].id}`);
});

Then(/^the (first|second) feature (?:is|will be) displayed$/, function (featureIndex) {
const index = featureIndex === 'first' ? 0 : 1;
const featureWrappers = this.outputHTML.getElementsByClassName('feature-wrapper');
Expand Down
16 changes: 13 additions & 3 deletions features/support/world.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const { setWorldConstructor, After, Before } = require('cucumber');
const { JSDOM } = require('jsdom');
const { JSDOM, VirtualConsole } = require('jsdom');
const fs = require('fs');

class CustomWorld {
Expand All @@ -14,11 +14,21 @@ class CustomWorld {
this.exceptionScenario = false;
}

createWindow(url, outputConsole) {
const virtualConsole = new VirtualConsole();
if (outputConsole) {
virtualConsole.sendTo(outputConsole);
}
this.window = new JSDOM(this.output, {
url, virtualConsole, runScripts: 'dangerously', pretendToBeVisual: true,
}).window;
this.outputHTML = this.window.document;
}

setOutput(output) {
this.output = output;
if (this.output.length > 0) {
this.window = new JSDOM(this.output, { url: 'https://localhost/', runScripts: 'dangerously', pretendToBeVisual: true }).window;
this.outputHTML = this.window.document;
this.createWindow('https://localhost/', console);
} else {
this.window = null;
this.outputHTML = null;
Expand Down
20 changes: 20 additions & 0 deletions features/use_report.feature
Original file line number Diff line number Diff line change
Expand Up @@ -122,3 +122,23 @@ Feature: Report Usage
Then the tags displayed for the feature will be '@pet_care @dogs'
Then the tags displayed for the first scenario will be '@feeding'
Then the tags displayed for the second scenario will be '@petting'

Scenario: Opening a report with a feature title link
Given there is a report for the 'feature' directory
When the report is opened with a link for the second feature title
Then the second feature will be displayed
And the scenario buttons for the second feature will be expanded in the sidebar
When the report is opened with a link for the first feature title
Then the first feature will be displayed
And the scenario buttons for the first feature will be expanded in the sidebar

Scenario: Opening a report with a scenario title link
Given there is a report for the 'feature' directory
When the report is opened with a link for the second scenario title in the second feature
Then the second feature will be displayed
And the scenario buttons for the second feature will be expanded in the sidebar
And the second scenario button will be highlighted
When the report is opened with a link for the first scenario title in the first feature
Then the first feature will be displayed
And the scenario buttons for the first feature will be expanded in the sidebar
And the first scenario button will be highlighted
3 changes: 3 additions & 0 deletions src/Generator.js
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,8 @@ const populateHtmlIdentifiers = (feature) => {
idSequence += 1;
feature.featureWrapperId = idSequence;
idSequence += 1;
feature.featureButtonId = idSequence;
idSequence += 1;
feature.scenarios.forEach((scenario) => {
scenario.scenarioId = idSequence;
idSequence += 1;
Expand Down Expand Up @@ -289,6 +291,7 @@ const getFeatureButtons = (featureFileTree) => {
const { feature } = child;
const translations = i18n.getFixedT(feature.language);
const featureButton = {
id: feature.featureButtonId,
featureId: feature.featureId,
featureWrapperId: feature.featureWrapperId,
title: trimCucumberKeywords(translations, feature.name, 'feature'),
Expand Down
16 changes: 12 additions & 4 deletions src/templates/feature_template.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,12 @@
{{#if tagString}}
<div class="tags">{{tagString}}</div>
{{/if}}
<a class="anchor" id="{{featureId}}"></a>
<h2>{{name}}</h2>
<h2>
<span class="title">{{name}}</span>
<a class="anchor" id="{{featureId}}" feature-button="{{featureButtonId}}" href="#{{featureId}}">
<i class="fas fa-link"></i>
</a>
</h2>
<div class="feature-body">
<div class="feature-description"><pre><i>{{description}}</i></pre></div>

Expand Down Expand Up @@ -41,8 +45,12 @@ <h3>{{this.background.name}}</h3>
{{#if tagString}}
<div class="tags">{{tagString}}</div>
{{/if}}
<a class="anchor" id="{{scenarioId}}" scenario-button="{{scenarioButtonId}}"></a>
<h3>{{this.name}}</h3>
<h3>
<span class="title">{{this.name}}</span>
<a class="anchor" id="{{scenarioId}}" scenario-button="{{scenarioButtonId}}" href="#{{scenarioId}}">
<i class="fas fa-link"></i>
</a>
</h3>
<div class="scenario-body">
{{#if this.description}}
<div class="scenario-description"><pre><i>{{this.description}}</i></pre></div>
Expand Down
48 changes: 39 additions & 9 deletions src/templates/scripts.js
Original file line number Diff line number Diff line change
Expand Up @@ -179,15 +179,45 @@ const init = () => {
tagsCheckbox.addEventListener('click', tagsCheckboxClicked);
}

// Open the first feature.
const firstFeatureButton = document.getElementsByClassName('feature-button')[0];
if (firstFeatureButton) {
// Open any parent directory buttons
const directoryButton = firstFeatureButton.parentNode.parentNode.previousElementSibling;
toggleParentDirectoryButtons(directoryButton);

toggleFunctionAccordion(firstFeatureButton);
toggleDisplayedFeature(firstFeatureButton);
// Open the identified feature/scenario (if specified in the URL) else open the first feature
const { hash } = window.location;
let openDefaultFeature = true;
if (hash) {
const elementId = hash.substring(1, hash.length);
const element = document.getElementById(elementId);
if (element) {
const scenarioButtonId = element.getAttribute('scenario-button');
const featureButtonId = element.getAttribute('feature-button');
if (scenarioButtonId) {
// It is a scenario link
const scenarioButton = document.getElementById(scenarioButtonId);
const featureButton = scenarioButton.parentNode.parentNode.previousElementSibling;
const directoryButton = featureButton.parentNode.parentNode.previousElementSibling;
toggleParentDirectoryButtons(directoryButton);
featureButton.click();
scenarioButton.click();
openDefaultFeature = false;
} else if (featureButtonId) {
// It is a feature link
const featureButton = document.getElementById(featureButtonId);
const directoryButton = featureButton.parentNode.parentNode.previousElementSibling;
toggleParentDirectoryButtons(directoryButton);
featureButton.click();
openDefaultFeature = false;
}
}
}
if (openDefaultFeature) {
// Open the first feature.
const firstFeatureButton = document.getElementsByClassName('feature-button')[0];
if (firstFeatureButton) {
// Open any parent directory buttons
const directoryButton = firstFeatureButton.parentNode.parentNode.previousElementSibling;
toggleParentDirectoryButtons(directoryButton);

toggleFunctionAccordion(firstFeatureButton);
toggleDisplayedFeature(firstFeatureButton);
}
}

// Initialize the settings
Expand Down
11 changes: 7 additions & 4 deletions src/templates/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -179,10 +179,13 @@ i.fa-angle-right, i.fa-angle-down {
.feature-wrapper.active {
display: block;
}
.feature-wrapper a.anchor {
display: block;
position: relative;
top: -1.5em;
.anchor {
color: transparent;
padding-top: 1em;
outline: none;
}
.title:hover + .anchor, .anchor:hover {
color: -webkit-link;
}
.tags {
color: grey;
Expand Down

0 comments on commit 6925967

Please sign in to comment.