Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

[allure-adaptor] Add ability to configure report layout #5423

Merged
merged 1 commit into from
Oct 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
118 changes: 117 additions & 1 deletion docs/modules/configuration/pages/reporting.adoc
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
= Reporting Configuration

== Configure report layout
== Configure report translations and layout

[cols="3,2,1,3", options="header"]
|===
Expand Down Expand Up @@ -39,6 +39,122 @@ be used:
report.translations.en.chart.duration.empty=No data to display
----

4+^.^|[#_report_layout]_Report Layout_

|`report.tabs.categories.enabled`
a|`true` +
`false`
|`true`
|Show or hide menu:Categories[] tab

|`report.tabs.suites.enabled`
a|`true` +
`false`
|`true`
|Show or hide menu:Suites[] (aka menu:Batches[]) tab
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image
Is this expected format of messages (I about '[]') ?
Shouldn't we add spaces after the colon?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, it is, rendering is not correct without square brackets and no space is expected after colon: https://docs.asciidoctor.org/asciidoc/latest/macros/ui-macros/


|`report.tabs.graph.enabled`
a|`true` +
`false`
|`true`
|Show or hide menu:Graphs[] tab

|`report.tabs.timeline.enabled`
a|`true` +
`false`
|`true`
|Show or hide menu:Timeline[] tab

|`report.tabs.behaviors.enabled`
a|`true` +
`false`
|`true`
|Show or hide menu:Behaviors[] tab

|`report.tabs.overview.widgets.summary.enabled`
a|`true` +
`false`
|`true`
|Show or hide menu:Summary[] widget on menu:Overview[] tab

|`report.tabs.overview.widgets.suites.enabled`
a|`true` +
`false`
|`true`
|Show or hide menu:Suites[] (aka menu:Batches[]) widget on menu:Overview[] tab

|`report.tabs.overview.widgets.environment.enabled`
a|`true` +
`false`
|`true`
|Show or hide menu:Environment[] widget on menu:Overview[] tab

|`report.tabs.overview.widgets.history-trend.enabled`
a|`true` +
`false`
|`true`
|Show or hide menu:Trend[] widget on menu:Overview[] tab

|`report.tabs.overview.widgets.categories.enabled`
a|`true` +
`false`
|`true`
|Show or hide menu:Categories[] widget on menu:Overview[] tab

|`report.tabs.overview.widgets.behaviors.enabled`
a|`true` +
`false`
|`true`
|Show or hide menu:Features by Stories[] widget on menu:Overview[] tab

|`report.tabs.overview.widgets.executors.enabled`
a|`true` +
`false`
|`true`
|Show or hide menu:Executors[] widget on menu:Overview[] tab

|`report.tabs.graph.charts.status-chart.enabled`
a|`true` +
`false`
|`true`
|Show or hide menu:Status[] chart on menu:Graphs[] tab

|`report.tabs.graph.charts.severity.enabled`
a|`true` +
`false`
|`true`
|Show or hide menu:Severity[] chart on menu:Graphs[] tab

|`report.tabs.graph.charts.duration.enabled`
a|`true` +
`false`
|`true`
|Show or hide menu:Duration[] chart on menu:Graphs[] tab

|`report.tabs.graph.charts.duration-trend.enabled`
a|`true` +
`false`
|`true`
|Show or hide menu:Duration Trend[] chart on menu:Graphs[] tab

|`report.tabs.graph.charts.retry-trend.enabled`
a|`true` +
`false`
|`true`
|Show or hide menu:Retry Trend[] chart on menu:Graphs[] tab

|`report.tabs.graph.charts.categories-trend.enabled`
a|`true` +
`false`
|`true`
|Show or hide menu:Categories Trend[] chart on menu:Graphs[] tab

|`report.tabs.graph.charts.history-trend.enabled`
a|`true` +
`false`
|`true`
|Show or hide menu:Trend[] chart on menu:Graphs[] tab

|===

== Add metadata
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,70 +17,28 @@
package org.vividus.report.allure.plugin;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.attribute.PosixFilePermission;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.lang3.SystemUtils;
import org.vividus.util.ResourceUtils;
import org.vividus.util.json.JsonUtils;
import org.vividus.util.property.PropertyMappedCollection;

import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import io.qameta.allure.PluginConfiguration;
import io.qameta.allure.plugin.DefaultPlugin;

public class CustomTranslationsPlugin extends DefaultPlugin
public class CustomTranslationsPlugin extends DynamicPlugin
{
private static final String INDEX_JS = "index.js";
private final Map<String, Path> pluginFiles = new HashMap<>();

@SuppressFBWarnings("CT_CONSTRUCTOR_THROW")
public CustomTranslationsPlugin(PropertyMappedCollection<Map<String, ?>> customTranslations, JsonUtils jsonUtils)
throws IOException
{
super(new PluginConfiguration()
.setId("custom-translations")
.setJsFiles(List.of()),
List.of(), null);

if (!customTranslations.getData().isEmpty())
{
super("custom-translations", () -> {
List<String> jsFileLines = new ArrayList<>();
jsFileLines.add("'use strict';");
customTranslations.getData().forEach((lang, value) -> jsFileLines.add(
"allure.api.addTranslation('%s', %s);".formatted(lang, jsonUtils.toJson(value))
"allure.api.addTranslation('%s', %s);".formatted(lang, jsonUtils.toJson(value))
)
);

Path indexJs = ResourceUtils.createTempFile("index", ".js");
Files.write(indexJs, jsFileLines);

/**
* For UNIX like operation systems default access for temp files is 600, whereas for regular files the
* default access is 644, so the following fix is used to align access bits across all files being created
* during test execution and avoid potential access related issues.
*/
if (SystemUtils.IS_OS_UNIX)
{
Files.setPosixFilePermissions(indexJs,
Set.of(PosixFilePermission.OWNER_WRITE, PosixFilePermission.OWNER_READ,
PosixFilePermission.GROUP_READ, PosixFilePermission.OTHERS_READ));
}

this.pluginFiles.put(INDEX_JS, Path.of(indexJs.toUri()));
getConfig().setJsFiles(List.of(INDEX_JS));
}
}

@Override
public Map<String, Path> getPluginFiles()
{
return pluginFiles;
return jsFileLines;
});
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/*
* Copyright 2019-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.vividus.report.allure.plugin;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.attribute.PosixFilePermission;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Supplier;
import java.util.stream.Stream;

import org.apache.commons.lang3.SystemUtils;
import org.vividus.util.ResourceUtils;

import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import io.qameta.allure.PluginConfiguration;
import io.qameta.allure.plugin.DefaultPlugin;

public class DynamicPlugin extends DefaultPlugin
{
private static final String INDEX_JS = "index.js";

private final Map<String, Path> pluginFiles = new HashMap<>();

@SuppressFBWarnings("CT_CONSTRUCTOR_THROW")
public DynamicPlugin(String pluginId, Supplier<List<String>> jsFileLinesSupplier) throws IOException
{
super(new PluginConfiguration()
.setId(pluginId)
.setJsFiles(List.of()),
List.of(), null);

List<String> jsFileLines = jsFileLinesSupplier.get();

if (!jsFileLines.isEmpty())
{
Path indexJs = ResourceUtils.createTempFile("index", ".js");
Files.write(indexJs, Stream.of(List.of("'use strict';"), jsFileLines).flatMap(List::stream).toList());

/*
For UNIX like operating systems default access for temp files is 600, whereas for regular files the
default access is 644, so the following fix is used to align access bits across all files being created
during test execution and avoid potential access related issues.
*/
if (SystemUtils.IS_OS_UNIX)
{
Files.setPosixFilePermissions(indexJs,
Set.of(PosixFilePermission.OWNER_WRITE, PosixFilePermission.OWNER_READ,
PosixFilePermission.GROUP_READ, PosixFilePermission.OTHERS_READ));
}

pluginFiles.put(INDEX_JS, Path.of(indexJs.toUri()));
getConfig().setJsFiles(List.of(INDEX_JS));
}
}

@Override
public Map<String, Path> getPluginFiles()
{
return pluginFiles;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
/*
* Copyright 2019-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.vividus.report.allure.plugin;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map.Entry;
import java.util.stream.Collectors;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

import org.vividus.util.property.PropertyMappedCollection;

import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;

public class LayoutConfiguringPlugin extends DynamicPlugin
{
@SuppressFBWarnings("CT_CONSTRUCTOR_THROW")
public LayoutConfiguringPlugin(PropertyMappedCollection<Component> tabs,
PropertyMappedCollection<Component> widgets, PropertyMappedCollection<Component> charts) throws IOException
{
super("layout-configuration", () -> {
List<String> jsFileLines = new ArrayList<>();

String tabsToExclude = tabs.getData().entrySet().stream()
.filter(e -> e.getValue().isDisabled())
.map(Entry::getKey)
.map("'%s'"::formatted)
.collect(Collectors.joining(","));
if (!tabsToExclude.isEmpty())
{
jsFileLines.add("allure.api.tabs = allure.api.tabs.filter(t => ![%s].includes(t.tabName));".formatted(
tabsToExclude));
}

addJsLinesDisablingComponents(widgets, "delete allure.api.widgets.widgets['%s'];", jsFileLines);
addJsLinesDisablingComponents(charts, "delete allure.api.widgets.graph['%s'];", jsFileLines);

return jsFileLines;
});
}

private static void addJsLinesDisablingComponents(PropertyMappedCollection<Component> components,
String jsLineFormat, List<String> jsFileLines)
{
components.getData().entrySet().stream()
.filter(e -> e.getValue().isDisabled())
.map(Entry::getKey)
.map(jsLineFormat::formatted)
.forEach(jsFileLines::add);
}

@JsonIgnoreProperties(ignoreUnknown = true)
public static final class Component
{
private Boolean enabled;

public Boolean isEnabled()
{
return enabled;
}

public void setEnabled(Boolean enabled)
{
this.enabled = enabled;
}

public boolean isDisabled()
{
return Boolean.FALSE.equals(isEnabled());
}
}
}
Loading
Loading