{ "pbiEntries": [ { "name": "reportLayout", "pbixEntryPath": "Report/Layout", "pbipEntryPath": "report.json", "contentType": "json", "codepage": 1200, "rules": [ { "id": "CHARTS_WIDER_THAN_TALL", "name": "Charts wider than tall", "description": "Want to check that your charts are wider than tall?", "disabled": false, "logType": "warning", "forEachPath": "$.sections[*]", "forEachPathName": "$.name", "forEachPathDisplayName": "$.displayName", "path": "$.visualContainers[*].config", "pathErrorWhenNoMatch": false, "test": [ { "map": [ { "filter": [ { "var": "visualsConfigArray" }, { "<": [ { "var": "layouts.0.position.width" }, { "var": "layouts.0.position.height" } ] } ] }, { "var": "name" } ] }, { "visualsConfigArray": "." }, [] ] }, { "id": "DISABLE_SLOW_DATASOURCE_SETTINGS", "name": "Disable local slow datasource settings", "description": "Check that report slow data source settings are all disabled.", "disabled": false, "logType": "warning", "path": "$.config", "pathErrorWhenNoMatch": true, "test": [ { "!": [ { "or": [ { "var": "isCrossHighlightingDisabled" }, { "var": "isSlicerSelectionsButtonEnabled" }, { "var": "isFilterSelectionsButtonEnabled" }, { "var": "isFieldWellButtonEnabled" }, { "var": "isApplyAllButtonEnabled" } ] } ] }, { "isCrossHighlightingDisabled": "/slowDataSourceSettings/isCrossHighlightingDisabled", "isSlicerSelectionsButtonEnabled": "/slowDataSourceSettings/isSlicerSelectionsButtonEnabled", "isFilterSelectionsButtonEnabled": "/slowDataSourceSettings/isFilterSelectionsButtonEnabled", "isFieldWellButtonEnabled": "/slowDataSourceSettings/isFieldWellButtonEnabled", "isApplyAllButtonEnabled": "/slowDataSourceSettings/isApplyAllButtonEnabled" }, true ] }, { "id": "LOCAL_REPORT_SETTINGS", "name": "Local report settings", "disabled": false, "logType": "warning", "description": "Check local report settings other than slow data source settings. This rule creates a json record of current local setting values and compares to a json record of expected values. Currently, if this rules fails, I recommend comparing both output json records formatted in Visual Studio code to easily identify the failed setting values.", "path": "$.config", "pathErrorWhenNoMatch": false, "test": [ { "torecord": [ "activePageIndex", { "var": "activePageIndex" }, "defaultDrillFilterOtherVisuals", { "var": "defaultDrillFilterOtherVisuals" }, "isPersistentUserStateDisabled", { "var": "isPersistentUserStateDisabled" }, "hideVisualContainerHeader", { "var": "hideVisualContainerHeader" }, "useStylableVisualContainerHeader", { "var": "useStylableVisualContainerHeader" }, "exportDataMode", { "var": "exportDataMode" }, "useNewFilterPaneExperience", { "var": "useNewFilterPaneExperience" }, "optOutNewFilterPaneExperience", { "var": "optOutNewFilterPaneExperience" }, "defaultFilterActionIsDataFilter", { "var": "defaultFilterActionIsDataFilter" }, "useCrossReportDrillthrough", { "var": "useCrossReportDrillthrough" }, "allowChangeFilterTypes", { "var": "allowChangeFilterTypes" }, "allowInlineExploration", { "var": "allowInlineExploration" }, "disableFilterPaneSearch", { "var": "disableFilterPaneSearch" }, "enableDeveloperMode", { "if": [ { "!!": [ { "var": "enableDeveloperMode" } ] }, { "var": "enableDeveloperMode" }, false ] }, "useEnhancedTooltips", { "var": "useEnhancedTooltips" }, "useDefaultAggregateDisplayName", { "var": "useDefaultAggregateDisplayName" } ] }, { "activePageIndex": "/activeSectionIndex", "defaultDrillFilterOtherVisuals": "/defaultDrillFilterOtherVisuals", "isPersistentUserStateDisabled": "/settings/isPersistentUserStateDisabled", "hideVisualContainerHeader": "/settings/hideVisualContainerHeader", "useStylableVisualContainerHeader": "/settings/useStylableVisualContainerHeader", "exportDataMode": "/settings/exportDataMode", "useNewFilterPaneExperience": "/settings/useNewFilterPaneExperience", "optOutNewFilterPaneExperience": "/settings/optOutNewFilterPaneExperience", "defaultFilterActionIsDataFilter": "/settings/defaultFilterActionIsDataFilter", "useCrossReportDrillthrough": "/settings/useCrossReportDrillthrough", "allowChangeFilterTypes": "/settings/allowChangeFilterTypes", "allowInlineExploration": "/settings/allowInlineExploration", "disableFilterPaneSearch": "/settings/disableFilterPaneSearch", "enableDeveloperMode": "/settings/enableDeveloperMode", "useEnhancedTooltips": "/settings/useEnhancedTooltips", "useDefaultAggregateDisplayName": "/settings/useDefaultAggregateDisplayName" }, { "activePageIndex": 0, "defaultDrillFilterOtherVisuals": true, "isPersistentUserStateDisabled": true, "hideVisualContainerHeader": false, "useStylableVisualContainerHeader": true, "exportDataMode": 1, "useNewFilterPaneExperience": true, "optOutNewFilterPaneExperience": false, "defaultFilterActionIsDataFilter": true, "useCrossReportDrillthrough": false, "allowChangeFilterTypes": true, "allowInlineExploration": false, "disableFilterPaneSearch": false, "enableDeveloperMode": false, "useEnhancedTooltips": true, "useDefaultAggregateDisplayName": true } ] }, { "id": "SHOW_AXES_TITLES", "name": "Show visual axes titles", "description": "Check that certain charts have both axes title showing.", "disabled": false, "logType": "warning", "forEachPath": "$.sections[*]", "forEachPathName": "$.name", "forEachPathDisplayName": "$.displayName", "path": "$.visualContainers[*].config", "pathErrorWhenNoMatch": false, "test": [ { "map": [ { "filter": [ { "var": "visualsConfigArray" }, { "and": [ { "in": [ { "var": "singleVisual.visualType" }, [ "lineChart", "barChart", "columnChart", "clusteredBarChart", "stackedBarChart" ] ] }, { "or": [ { "==": [ { "var": "singleVisual.objects.categoryAxis.0.properties.showAxisTitle.expr.Literal.Value" }, "false" ] }, { "==": [ { "var": "singleVisual.objects.valueAxis.0.properties.showAxisTitle.expr.Literal.Value" }, "false" ] } ] } ] } ] }, { "var": "name" } ] }, { "visualsConfigArray": "." }, [] ] }, { "id": "PERCENTAGE_OF_CHARTS_USING_CUSTOM_COLOURS", "name": "Percentage of charts across the report using custom colours is not greater than 10%", "description": "Check that charts avoid custom colours and use theme colours instead.", "disabled": false, "logType": "warning", "path": "$.sections[*].visualContainers[*].config", "pathErrorWhenNoMatch": true, "test": [ { "<=": [ { "/": [ { "count": [ { "filter": [ { "var": "visualConfigArray" }, { "and": [ { "!": [ { "in": [ { "var": "singleVisual.visualType" }, [ "textbox" ] ] } ] }, { "strcontains": [ { "tostring": [ { "var": "" } ] }, "#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})" ] } ] } ] } ] }, { "count": [ { "filter": [ { "var": "visualConfigArray" }, { "!": [ { "in": [ { "var": "singleVisual.visualType" }, [ "textbox" ] ] } ] } ] } ] } ] }, { "var": "paramMaxAllowedRatio" } ] }, { "visualConfigArray": ".", "paramMaxAllowedRatio": 0.1 }, true ] }, { "id": "ENSURE_ALT_TEXT_DEFINED_FOR_VISUALS", "name": "Ensure alt-text has been defined for visuals", "description": "Alt-text is required for screen readers.", "disabled": true, "logType": "warning", "forEachPath": "$.sections[*]", "forEachPathName": "$.name", "forEachPathDisplayName": "$.displayName", "path": "$.visualContainers[*].config", "pathErrorWhenNoMatch": false, "test": [ { "map": [ { "filter": [ { "var": "visualsConfigArray" }, { "and": [ { "!": [ { "in": [ { "var": "singleVisual.visualType" }, [ "shape" ] ] } ] }, { "none": [ { "var": "singleVisual.vcObjects.general" }, { "or": [ { "!!": [ { "var": "properties.altText.expr.Aggregation" } ] }, { "!=": [ { "var": "properties.altText.expr.Literal.Value" }, "''" ] } ] } ] } ] } ] }, { "var": "name" } ] }, { "visualsConfigArray": "." }, [] ] }, { "id": "DISABLE_DROP_SHADOWS_ON_VISUALS", "name": "Disable drop shadows on visuals", "description": "Drop shadows are not suitable for everyone, this rule returns an array of visuals with drop shadows enabled.", "disabled": false, "logType": "warning", "forEachPath": "$.sections[*]", "forEachPathName": "$.name", "forEachPathDisplayName": "$.displayName", "path": "$.visualContainers[*].config", "pathErrorWhenNoMatch": false, "test": [ { "map": [ { "filter": [ { "var": "visualsConfigArray" }, { "some": [ { "var": "singleVisual.vcObjects.dropShadow" }, { "==": [ { "var": "properties.show.expr.Literal.Value" }, "true" ] } ] } ] }, { "var": "name" } ] }, { "visualsConfigArray": "." }, [] ] }, { "id": "GIVE_VISIBLE_PAGES_MEANINGFUL_NAMES", "name": "Give visible pages meaningful names", "description": "Returns an array of visible page names with a default 'Page x' display name.", "disabled": false, "logType": "warning", "path": "$.sections[*]", "pathErrorWhenNoMatch": false, "test": [ { "map": [ { "filter": [ { "var": "pageArray" }, { "and": [ { "strcontains": [ { "var": "displayName" }, "^Page [1-9]+$" ] }, { "!=": [ { "drillvar": "config>visibility" }, 1 ] } ] } ] }, { "var": "displayName" } ] }, { "pageArray": "." }, [] ] }, { "id": "DENEB_CHARTS_PROPERTIES", "name": "Check Deneb charts properties - work in progress", "description": "Checks that the drillvar custom rule can read deneb custom visual nested jsonspec properties. This is an example in progress that demonstrates the use of the drillvar custom rule but doesn't yet do anything useful.", "disabled": true, "logType": "warning", "path": "$.sections[*]", "pathErrorWhenNoMatch": true, "test": [ { "map": [ { "filter": [ { "var": "pageArray" }, { "and": [ { "strcontains": [ { "drillvar": "visualContainers.0.config>singleVisual.visualType" }, "^deneb[A-Z0-9]+$" ] }, { "==": [ { "drillvar": "visualContainers.0.config>singleVisual.objects.vega.0.properties.jsonSpec.expr.Literal.Value>data.name" }, "dataset" ] } ] } ] }, { "var": "displayName" } ] }, { "pageArray": "." }, [] ] }, { "id": "CHECK_FOR_VISUALS_OVERLAP", "name": "Check for visuals overlap with a 5px margin", "description": "Returns names of visuals that overlap while inflating visuals rectangle area by 5px left, right, top and bottom. Currently this does not check for overlap with the sides of report page itself. This rule does not currently work with visual groups.", "disabled": false, "logType": "warning", "forEachPath": "$.sections[*]", "forEachPathName": "$.name", "forEachPathDisplayName": "$.displayName", "path": "$.visualContainers[*].config", "pathErrorWhenNoMatch": false, "test": [ { "rectoverlap": [ { "map": [ { "filter": [ { "var": "v" }, { "and": [ { "!!": [ { "var": "name" } ] }, { "!": [ { "in": [ { "var": "singleVisual.visualType" }, [ "card", "slicer", "actionButton" ] ] } ] }, { ">=": [ { "var": "layouts.0.position.x" }, 0 ] }, { ">=": [ { "var": "layouts.0.position.y" }, 0 ] }, { ">=": [ { "var": "layouts.0.position.width" }, 0 ] }, { ">=": [ { "var": "layouts.0.position.height" }, 0 ] }, { "!=": [ { "var": "singleVisual.display.mode" }, "hidden" ] } ] } ] }, { "torecord": [ "name", { "var": "name" }, "x", { "var": "layouts.0.position.x" }, "y", { "var": "layouts.0.position.y" }, "width", { "var": "layouts.0.position.width" }, "height", { "var": "layouts.0.position.height" } ] } ] }, 5 ] }, { "v": "." }, [] ] }, { "id": "CHECK_FOR_LOCAL_MEASURES", "name": "Check for locally defined measures", "description": "Returns an array of report-level measure definitions", "path": "$.config", "pathErrorWhenNoMatch": false, "test": [ { "filter": [ { "var": "modelExt" }, { "and": [ { "==": [ { "var": "name" }, "extension" ] }, { "some": [ { "var": "entities" }, { ">": [ { "count": [ { "var": "measures" } ] }, 0 ] } ] } ] } ] }, { "modelExt": "/modelExtensions" }, [] ] } ] }, { "name": "Report theme", "description": "Check report theme properties.", "pbixEntryPath": "Report/StaticResources/SharedResources/BaseThemes/CY22SU11.json", "pbipEntryPath": "StaticResources/SharedResources/BaseThemes/CY22SU11.json", "contentType": "json", "codepage": 65001, "rules": [ { "id": "REPORT_THEME_NAME", "name": "Report theme name", "description": "Check Report theme name", "disabled": false, "logType": "warning", "path": "$", "pathErrorWhenNoMatch": true, "test": [ { "==": [ { "var": "n" }, "CY22SU09" ] }, { "n": "/name" }, true ] }, { "id": "REPORT_THEME_TITLE_FONT", "name": "Report theme title font properties", "description": "Checks theme's' title foreground, fontface and fontsize", "disabled": false, "logType": "warning", "path": "$", "pathErrorWhenNoMatch": true, "test": [ { "and": [ { "==": [ { "var": "foreground" }, "#252423" ] }, { "==": [ { "var": "fontface" }, "DIN" ] }, { ">=": [ { "var": "fontsize" }, 10 ] }, { "<=": [ { "var": "fontsize" }, 12 ] } ] }, { "foreground": "/foreground", "fontface": "/textClasses/title/fontFace", "fontsize": "/textClasses/title/fontSize" }, true ] } ] } ] }