From 49bd6def26ebe744de6de4e68b5d27500bc38d54 Mon Sep 17 00:00:00 2001 From: Tim de Groot Date: Sun, 24 May 2026 19:45:06 +0200 Subject: [PATCH 1/6] feat: implement custom sections feature with add, delete, and modal support --- robotframework_dashboard/css/components.css | 62 +++++ robotframework_dashboard/js/customsections.js | 224 ++++++++++++++++++ robotframework_dashboard/js/layout.js | 33 +++ robotframework_dashboard/js/localstorage.js | 6 +- .../templates/dashboard.html | 33 +++ 5 files changed, 356 insertions(+), 2 deletions(-) create mode 100644 robotframework_dashboard/js/customsections.js diff --git a/robotframework_dashboard/css/components.css b/robotframework_dashboard/css/components.css index d615d21f..7d53a559 100644 --- a/robotframework_dashboard/css/components.css +++ b/robotframework_dashboard/css/components.css @@ -193,6 +193,68 @@ min-width: 60px; } +/* Add custom section horizontal tile — shown in customize-view mode (unified grid only) */ +.add-section-tile { + cursor: pointer; + display: flex; + align-items: center; + justify-content: center; + border: 2px dashed var(--bs-border-color, rgba(128,128,128,0.4)); + border-radius: 8px; + transition: border-color 0.15s, background-color 0.15s; +} + +.add-section-tile:hover { + border-color: var(--color-text); + background-color: rgba(128,128,128,0.08); +} + +.add-section-tile-inner { + display: flex; + flex-direction: row; + align-items: center; + gap: 0.5rem; + user-select: none; +} + +.add-section-plus { + font-size: 1.5rem; + font-weight: 300; + line-height: 1; +} + +.add-section-tile-label { + font-size: 0.85rem; + font-weight: 500; +} + +/* Custom section divider bar rendered inside the unified GridStack */ +.custom-section-divider { + display: flex; + align-items: center; + padding: 0 1rem; + border-radius: 6px; + height: 100%; + width: 100%; + position: relative; +} + +.custom-section-title { + flex: 1; + font-size: 1rem; + font-weight: 600; + text-align: center; + user-select: none; +} + +/* Delete button on custom section dividers — pinned to top-right */ +.delete-custom-section { + position: absolute; + top: 5px; + right: 5px; + z-index: 1; +} + /* Delete button on custom stat widgets — pinned to top-right, out of flex flow */ .delete-custom-stat-widget { position: absolute; diff --git a/robotframework_dashboard/js/customsections.js b/robotframework_dashboard/js/customsections.js new file mode 100644 index 00000000..614a026c --- /dev/null +++ b/robotframework_dashboard/js/customsections.js @@ -0,0 +1,224 @@ +import { settings } from './variables/settings.js'; +import { set_local_storage_item } from './localstorage.js'; +import { STAT_WIDGET_COLORS, STAT_WIDGET_BG_COLORS } from './variables/statwidgetdefs.js'; + +// Generates a short random ID (safe across all modern browsers) +function generate_section_id() { + if (typeof crypto !== 'undefined' && crypto.randomUUID) { + return crypto.randomUUID().replace(/-/g, '').slice(0, 12); + } + return Math.random().toString(36).slice(2, 14); +} + +// Applies (or updates) the bg class on the grid-stack-item-content of a section item el +function apply_section_bg_class(itemEl, bgColor) { + const content = itemEl.querySelector('.grid-stack-item-content'); + if (!content) return; + content.classList.remove('blue-bg', 'green-bg', 'red-bg', 'yellow-bg'); + if (bgColor) content.classList.add(bgColor); +} + +// Builds the inner HTML for a custom section divider bar +function build_section_divider_html(section, editMode) { + const deleteBtn = editMode + ? `` + : ''; + return `
+ ${section.title} + ${deleteBtn} +
`; +} + +// Adds all custom section dividers (for unified grid) to the provided GridStack +function render_custom_sections(gridStack, editMode) { + const savedLayout = settings.layouts?.['gridUnified'] + ? JSON.parse(settings.layouts['gridUnified']) + : null; + + const sections = settings.customSections || []; + for (const section of sections) { + const saved = savedLayout?.find(l => l.id === `customSection-${section.id}`); + + const item = document.createElement('div'); + item.classList.add('grid-stack-item'); + item.setAttribute('gs-w', saved ? saved.w : 12); + item.setAttribute('gs-h', saved ? saved.h : 1); + item.setAttribute('gs-min-w', 12); + item.setAttribute('gs-max-w', 12); + item.setAttribute('gs-min-h', 1); + item.setAttribute('gs-max-h', 3); + if (saved) { + item.setAttribute('gs-x', saved.x); + item.setAttribute('gs-y', saved.y); + } + item.setAttribute('data-gs-id', `customSection-${section.id}`); + item.innerHTML = `
${build_section_divider_html(section, editMode)}
`; + gridStack.makeWidget(item); + apply_section_bg_class(item, section.bgColor); + } +} + +// Adds a special "Add custom section" horizontal tile to the unified GridStack for edit mode +function render_add_section_tile(gridStack) { + const tileId = 'addSectionTile-unified'; + if (gridStack.el.querySelector(`[data-gs-id="${tileId}"]`)) return; + + const item = document.createElement('div'); + item.classList.add('grid-stack-item'); + item.setAttribute('gs-w', 12); + item.setAttribute('gs-h', 1); + item.setAttribute('gs-min-w', 12); + item.setAttribute('gs-max-w', 12); + item.setAttribute('gs-min-h', 1); + item.setAttribute('gs-max-h', 1); + item.setAttribute('gs-no-resize', 'true'); + item.setAttribute('data-gs-id', tileId); + item.innerHTML = `
+
+
+
+
Add custom section
+
+
`; + gridStack.makeWidget(item); + item.querySelector('.add-section-tile').addEventListener('click', () => { + open_add_custom_section_modal(); + }); +} + +// Saves a new custom section divider to localStorage and returns it +function add_custom_section(title, bgColor, textColor) { + const id = generate_section_id(); + const section = { id, title, bgColor, textColor }; + const list = settings.customSections ? [...settings.customSections] : []; + list.push(section); + set_local_storage_item('customSections', list); + return section; +} + +// Removes a custom section divider from localStorage by its id +function remove_custom_section(id) { + const list = (settings.customSections || []).filter(s => s.id !== id); + set_local_storage_item('customSections', list); +} + +// Populates the background color picker in the Add Custom Section modal +function populate_section_bg_colors() { + const picker = document.getElementById('addCustomSectionBgColorPicker'); + if (!picker) return; + picker.innerHTML = ''; + for (const c of STAT_WIDGET_BG_COLORS) { + const btn = document.createElement('button'); + btn.type = 'button'; + btn.className = 'btn btn-outline-light btn-sm stat-color-btn'; + btn.dataset.color = c.value; + btn.textContent = c.label; + if (c.value === '') btn.classList.add('active'); + btn.addEventListener('click', () => { + picker.querySelectorAll('.stat-color-btn').forEach(b => b.classList.remove('active')); + btn.classList.add('active'); + }); + picker.appendChild(btn); + } +} + +// Populates the text color picker in the Add Custom Section modal +function populate_section_text_colors() { + const picker = document.getElementById('addCustomSectionTextColorPicker'); + if (!picker) return; + picker.innerHTML = ''; + for (const c of STAT_WIDGET_COLORS) { + const btn = document.createElement('button'); + btn.type = 'button'; + btn.className = 'btn btn-outline-light btn-sm stat-color-btn'; + btn.dataset.color = c.value; + btn.textContent = c.label; + if (c.value === 'white-text') btn.classList.add('active'); + btn.addEventListener('click', () => { + picker.querySelectorAll('.stat-color-btn').forEach(b => b.classList.remove('active')); + btn.classList.add('active'); + }); + picker.appendChild(btn); + } +} + +// Wires all events inside the Add Custom Section modal (call once after DOM ready) +function setup_add_custom_section_modal() { + populate_section_bg_colors(); + populate_section_text_colors(); + + document.getElementById('addCustomSectionConfirm')?.addEventListener('click', () => { + const titleInput = document.getElementById('addCustomSectionTitle'); + const title = titleInput?.value.trim() || 'Section'; + const bgColorBtn = document.querySelector('#addCustomSectionBgColorPicker .stat-color-btn.active'); + const bgColor = bgColorBtn?.dataset.color || ''; + const textColorBtn = document.querySelector('#addCustomSectionTextColorPicker .stat-color-btn.active'); + const textColor = textColorBtn?.dataset.color || 'white-text'; + + const section = add_custom_section(title, bgColor, textColor); + + const grid = window['gridUnified']; + if (grid) { + const item = document.createElement('div'); + item.classList.add('grid-stack-item'); + item.setAttribute('gs-w', 12); + item.setAttribute('gs-h', 1); + item.setAttribute('gs-min-w', 12); + item.setAttribute('gs-max-w', 12); + item.setAttribute('gs-min-h', 1); + item.setAttribute('gs-max-h', 3); + item.setAttribute('data-gs-id', `customSection-${section.id}`); + item.innerHTML = `
${build_section_divider_html(section, true)}
`; + grid.makeWidget(item); + apply_section_bg_class(item, section.bgColor); + const deleteBtn = item.querySelector(`.delete-custom-section[data-section-id="${section.id}"]`); + if (deleteBtn) { + deleteBtn.addEventListener('click', () => handle_delete_section(section.id, grid)); + } + } + + document.dispatchEvent(new CustomEvent("layout-user-action")); + + if (titleInput) titleInput.value = ''; + bootstrap.Modal.getInstance(document.getElementById('addCustomSectionModal'))?.hide(); + }); + + // Reset color pickers each time the modal opens + document.getElementById('addCustomSectionModal')?.addEventListener('show.bs.modal', () => { + populate_section_bg_colors(); + populate_section_text_colors(); + }); +} + +// Wires delete buttons on all currently rendered custom section dividers +function wire_delete_section_buttons(gridStack) { + const sections = settings.customSections || []; + for (const section of sections) { + const btn = document.querySelector(`.delete-custom-section[data-section-id="${section.id}"]`); + if (btn) { + btn.addEventListener('click', () => handle_delete_section(section.id, gridStack)); + } + } +} + +function handle_delete_section(id, gridStack) { + const el = gridStack?.el?.querySelector(`[data-gs-id="customSection-${id}"]`); + if (el && gridStack) { + gridStack.removeWidget(el); + } + remove_custom_section(id); + document.dispatchEvent(new CustomEvent("layout-user-action")); +} + +// Opens the Add Custom Section modal +function open_add_custom_section_modal() { + const modal = document.getElementById('addCustomSectionModal'); + if (!modal) return; + bootstrap.Modal.getOrCreateInstance(modal).show(); +} + +export { + render_custom_sections, + render_add_section_tile, + setup_add_custom_section_modal, + wire_delete_section_buttons, +}; diff --git a/robotframework_dashboard/js/layout.js b/robotframework_dashboard/js/layout.js index 43b19b62..085421b2 100644 --- a/robotframework_dashboard/js/layout.js +++ b/robotframework_dashboard/js/layout.js @@ -19,6 +19,12 @@ import { wire_delete_buttons, open_add_stat_widget_modal, } from "./statwidgets.js"; +import { + render_custom_sections, + render_add_section_tile, + setup_add_custom_section_modal, + wire_delete_section_buttons, +} from "./customsections.js"; // Layout history state for undo/redo in edit mode let layoutHistory = []; @@ -30,6 +36,7 @@ function capture_settings_snapshot() { return { layouts: JSON.parse(JSON.stringify(settings.layouts || {})), statWidgets: JSON.parse(JSON.stringify(settings.statWidgets || [])), + customSections: JSON.parse(JSON.stringify(settings.customSections || [])), view: { dashboard: { graphs: { @@ -73,6 +80,7 @@ function capture_dom_snapshot() { const snapshot = { layouts: {}, statWidgets: JSON.parse(JSON.stringify(settings.statWidgets || [])), + customSections: JSON.parse(JSON.stringify(settings.customSections || [])), view: { dashboard: { graphs: { show: [], hide: [] }, sections: { show: [], hide: [] } }, unified: { graphs: { show: [], hide: [] } }, @@ -121,6 +129,19 @@ function capture_dom_snapshot() { snapshot.view.tables.graphs.hide = hiddenTables; } + // Inactive mode's grids are empty in the DOM, so the scan above leaves their show/hide + // arrays as []. Preserve the current settings for whichever mode is not active so that + // undo/redo in one mode doesn't wipe the graph visibility of the other mode. + if (settings.show.unified) { + // Unified is active: dashboard section grids are empty, preserve their graph settings + snapshot.view.dashboard.graphs.show = JSON.parse(JSON.stringify(settings.view.dashboard.graphs.show || [])); + snapshot.view.dashboard.graphs.hide = JSON.parse(JSON.stringify(settings.view.dashboard.graphs.hide || [])); + } else { + // Dashboard is active: unified grid is empty, preserve its graph settings + snapshot.view.unified.graphs.show = JSON.parse(JSON.stringify(settings.view.unified.graphs.show || [])); + snapshot.view.unified.graphs.hide = JSON.parse(JSON.stringify(settings.view.unified.graphs.hide || [])); + } + // Dashboard section order and show/hide const shownDashSections = [...document.querySelectorAll("#dashboard .shown-section:not([hidden])")] .map(el => { @@ -163,6 +184,7 @@ function apply_layout_snapshot(snapshot) { applyingSnapshot = true; settings.layouts = JSON.parse(JSON.stringify(snapshot.layouts)); set_local_storage_item('statWidgets', JSON.parse(JSON.stringify(snapshot.statWidgets || []))); + set_local_storage_item('customSections', JSON.parse(JSON.stringify(snapshot.customSections || []))); settings.view.dashboard.graphs.show = [...snapshot.view.dashboard.graphs.show]; settings.view.dashboard.graphs.hide = [...snapshot.view.dashboard.graphs.hide]; settings.view.dashboard.sections.show = [...snapshot.view.dashboard.sections.show]; @@ -452,6 +474,15 @@ function setup_grid_graphs(section) { render_add_stat_widget_tile(window[grid], sectionKey); } } + + // Render custom section dividers (unified grid only) + if (section === "Unified") { + render_custom_sections(window[grid], gridEditMode); + if (gridEditMode) { + wire_delete_section_buttons(window[grid]); + render_add_section_tile(window[grid]); + } + } } function setup_tables() { @@ -730,6 +761,8 @@ function setup_dashboard_section_layout_buttons() { // Setup the add stat widget modal (populate dropdowns, wire confirm/cancel) setup_add_stat_widget_modal(); + // Setup the add custom section modal (populate color pickers, wire confirm/cancel) + setup_add_custom_section_modal(); } // function to separately add the eventlisteners for overview section layout buttons diff --git a/robotframework_dashboard/js/localstorage.js b/robotframework_dashboard/js/localstorage.js index 4ebb666c..5f3ee334 100644 --- a/robotframework_dashboard/js/localstorage.js +++ b/robotframework_dashboard/js/localstorage.js @@ -66,7 +66,7 @@ function merge_deep(local, defaults) { const defaultVal = defaults[key]; const localVal = local[key]; // Removed key: exists in local but not in defaults — EXCEPT layout, libraries, theme, filterProfiles, and statWidgets (only in localstorage) - if (key !== "layouts" && key !== "libraries" && key !== "theme" && key !== "filterProfiles" && key !== "statWidgets" && defaultVal === undefined && localVal !== undefined) { + if (key !== "layouts" && key !== "libraries" && key !== "theme" && key !== "filterProfiles" && key !== "statWidgets" && key !== "customSections" && defaultVal === undefined && localVal !== undefined) { continue; } // Added key: exists in defaults but not local: add defaults @@ -203,7 +203,9 @@ function merge_layout(localLayout, mergedDefaults) { const filtered = arr.filter(item => allowedGraphs.has(item.id) || // Preserve saved positions for user-created custom stat widgets - (typeof item.id === 'string' && item.id.startsWith('customStatWidget-')) + (typeof item.id === 'string' && item.id.startsWith('customStatWidget-')) || + // Preserve saved positions for user-created custom section dividers + (typeof item.id === 'string' && item.id.startsWith('customSection-')) ); result[key] = JSON.stringify(filtered); } catch (e) { diff --git a/robotframework_dashboard/templates/dashboard.html b/robotframework_dashboard/templates/dashboard.html index 9934722a..20da978f 100644 --- a/robotframework_dashboard/templates/dashboard.html +++ b/robotframework_dashboard/templates/dashboard.html @@ -1080,6 +1080,39 @@ + + + From ec3fa9a9bcd33295cf513bd97439518983a8b70d Mon Sep 17 00:00:00 2001 From: Tim de Groot Date: Sun, 24 May 2026 20:18:31 +0200 Subject: [PATCH 2/6] feat: add custom filters support and update documentation across multiple files --- docs/advanced-cli-examples.md | 17 +++ docs/basic-command-line-interface-cli.md | 178 +++++++++++++---------- docs/customization.md | 52 +++++-- docs/dashboard-server.md | 8 +- docs/filtering.md | 14 +- docs/listener-integration.md | 6 +- docs/settings.md | 55 +++++-- docs/tabs-pages.md | 2 +- 8 files changed, 223 insertions(+), 109 deletions(-) diff --git a/docs/advanced-cli-examples.md b/docs/advanced-cli-examples.md index 451a6cd1..f9c665b3 100644 --- a/docs/advanced-cli-examples.md +++ b/docs/advanced-cli-examples.md @@ -63,6 +63,23 @@ When using `project_` tags: - The `project_` prefix text can be shown or hidden using the **Prefixes** toggle in Settings - Multiple `project_` tags on different outputs allow comparing different projects side by side on the Overview page +## Custom Filters + +Custom filters let you attach arbitrary key=value metadata to runs and filter on them in the Dashboard's **Filters** modal. Each unique key becomes its own filter dropdown, independent of Run Tags. + +```bash +robotdashboard -o output.xml --customfilters "Environment=staging:ComponentA=2.0" +robotdashboard -f ./results --customfilters "ProductVersion=1.1:Region=EU" +``` + +- The argument takes a **colon-separated** list of `key=value` pairs. +- Each run can carry a different set of values. +- In the Dashboard, each key produces a dropdown with checkboxes for all unique values observed across runs, plus **All** (default) and **None** (runs with no value for that key). +- A **Mode** dropdown per dimension lets you switch between **OR** (default), **AND**, and **NOT** logic. +- Custom filter dropdowns are hidden when no runs in the database have custom filter data. + +> When using the [Listener](/listener-integration) or [Server Admin](/dashboard-server#adding-outputs) to push results, pass the same `key=value:key=value` string via the `customfilters` listener argument or the Custom Filters field in the admin page. + ## Aliases for Clean Dashboard Identification Aliases help replace long timestamps with clean, readable names. They also significantly improve clarity in comparison views and general dashboard readability. diff --git a/docs/basic-command-line-interface-cli.md b/docs/basic-command-line-interface-cli.md index 19b4cf11..3416b500 100644 --- a/docs/basic-command-line-interface-cli.md +++ b/docs/basic-command-line-interface-cli.md @@ -22,7 +22,7 @@ robotdashboard --help ``` - Optional: `-h` or `--help` provides detailed information about all CLI options. -## Adding Output XML Files +## Output Files ### Add one or multiple output XML files ```bash @@ -43,31 +43,6 @@ robotdashboard -f C:/nightly_runs:tag1:tag2:tag3 -f some/other/path/results - Tags can be added to group or categorize runs. - See [Advanced CLI & Examples](/advanced-cli-examples#advanced-tagging-strategies) for more information on Tags! -## Controlling Database and Dashboard Behavior - -### Custom database path -```bash -robotdashboard -d result_data/robot_result_database.db -``` -- Optional: `-d` or `--databasepath` specifies a custom database file to store results. -- Default: database path is the **current folder** with **robot_results.db**. - -### Custom dashboard HTML file name -```bash -robotdashboard -n results/result_robot_dashboard.html -``` -- Optional: `-n` or `--namedashboard` specifies the file name and path for the generated dashboard HTML. -- Default: dashboard name is **robot_dashboard_YYYYMMDD-HHMMSS.html**. - -### Skip listing runs and/or skip generating dashboard -```bash -robotdashboard -l false -g false -``` -- Optional: `-l` or `--listruns` disables listing runs in the console. -- Default: true, valid values are True, TRUE, T (similar for False). -- Optional: `-g` or `--generatedashboard` disables generating the HTML dashboard. -- Default: true, valid values are True, TRUE, T (similar for False). - ### Project Version You can pass version associated with a test run. For example, if you ran tests for your software/product version 1.2.1 @@ -89,6 +64,18 @@ robotdashboard -f ./results:version_1.1 ./results2:version_2.3.4 > Added in RobotDashboard v1.3.0 > version_ tag support added in v1.4.0 +### Custom Filters +You can attach arbitrary key=value metadata to runs as filterable dimensions. +```bash +robotdashboard -o output.xml --customfilters "ProductVersion=1.1:Environment=staging" +robotdashboard -f ./results --customfilters "ComponentA=2.0:Environment=prod" +``` +- Optional: `--customfilters` specifies one or more custom filter dimensions, as a colon-separated `key=value` string. +- Each unique key creates its own filter dropdown in the Dashboard's Filters modal. +- See [Advanced CLI & Examples](/advanced-cli-examples#custom-filters) for more details and the [Filtering](/filtering#global-filters) page for how custom filter dropdowns work. + +> Added in RobotDashboard v1.7.0 + ### Timezone The dashboard stores a timezone offset alongside `run_start` timestamps so the dashboard can display times correctly for your local timezone. By default the offset is **auto-detected** from the machine running `robotdashboard`. Override it when your `output.xml` files were produced in a different timezone: @@ -107,14 +94,21 @@ robotdashboard -o output.xml -z +00:00 ::: info Timezone and existing runs Runs processed **before** this feature was introduced have no timezone offset stored in their `run_start`. **This does not break anything** — those runs display exactly as they did before and are unaffected by both timezone settings in the dashboard. -You only need to re-add those `output.xml` files (with the correct `-z`/`--timezone` flag) if you want the **Convert Timestamps to Local Timezone** feature to work for them. If you never intend to use timezone conversion, no action is required. See [Upgrading & Database Migration](/installation-version-info#upgrading-database-migration) and [Settings – Display Timezone Offsets & Conversion](/settings#general-settings-graphs-tab) for details. +You only need to re-add those `output.xml` files (with the correct `-z`/`--timezone` flag) if you want the **Convert Timestamps to Local Timezone** feature to work for them. If you never intend to use timezone conversion, no action is required. See [Upgrading & Database Migration](/installation-version-info#upgrading-database-migration) and [Settings – Display Timezone Offsets & Conversion](/settings#labels-time-settings-labels-time-tab) for details. ::: > Added in RobotDashboard v1.8.0 -## Removing Runs from the Database +## Database -### Remove runs by index, run start, alias, tag, or limit +### Custom database path +```bash +robotdashboard -d result_data/robot_result_database.db +``` +- Optional: `-d` or `--databasepath` specifies a custom database file to store results. +- Default: database path is the **current folder** with **robot_results.db**. + +### Remove runs from the database ```bash robotdashboard -r index=0,index=1:4;9,index=10 robotdashboard --removeruns 'run_start=2024-07-30 15:27:20.184407,index=20' @@ -128,33 +122,51 @@ robotdashboard -r limit=10 - Quotation marks are required when spaces exist in identifiers. - With limit=10 only the 10 most recent runs will be kept, all others will be removed. -## Customizing the Dashboard +### Use a custom database class +```bash +robotdashboard -c ./path/to/custom_class.py +robotdashboard --databaseclass mysql.py +``` +- Optional: `-c` or `--databaseclass` specifies a custom database class implementation. +- By default, Sqlite3 is used. See [Custom Database Class](/custom-database-class.md) for more information. -### Set a custom HTML title +### Disable automatic database vacuuming ```bash -robotdashboard -t "My Cool Title" +robotdashboard --novacuum +robotdashboard --novacuum True ``` -- Optional: `-t` or `--dashboardtitle` sets a custom HTML title for the dashboard. -- Default: title is **Robot Framework Dashboard - YYYY-MM-DD HH:MM:SS**. -- The title also appears in the navigation bar of the dashboard, overriding any *Custom Title* value set in the Theme settings. -- It is also possible to combine all sections into a single unified view, see [Settings - General Settings (Graphs Tab)](/settings#general-settings-graphs-tab), for the details -- The unified title will be the same as the `-t, --dashboardtitle` argument if provided, otherwise it defaults to "Dashboard Statistics" +- Optional: `--novacuum` disables automatic database vacuuming. +- Default: False. Using `--novacuum` with no value sets it to True. -### Use a JSON dashboard configuration file to set default settings +## Dashboard + +### Generate dashboard and list runs ```bash -robotdashboard -j ./path/to/config.json -robotdashboard --jsonconfig default_settings.json +robotdashboard -g false +robotdashboard -l false +robotdashboard -l false -g false ``` -- Optional: `-j` or `--jsonconfig` sets a JSON dashboard configuration file used on first load. -- See [Advanced CLI & Examples](/advanced-cli-examples#using-a-custom-dashboard-config-json) for more information on customized loading behaviour! +- Optional: `-g` or `--generatedashboard` disables generating the HTML dashboard. +- Default: true, valid values are True, TRUE, T (similar for False). +- Optional: `-l` or `--listruns` disables listing runs in the console. +- Default: true, valid values are True, TRUE, T (similar for False). -### Force the JSON config even if local storage exists +### Custom dashboard HTML file name ```bash -robotdashboard -j ./path/to/config.json --forcejsonconfig -robotdashboard --jsonconfig default_settings.json --forcejsonconfig +robotdashboard -n results/result_robot_dashboard.html ``` -- Optional: `--forcejsonconfig` forces the use of the JSON dashboard configuration file even if local storage exists. -- See [Advanced CLI & Examples](/advanced-cli-examples#using-a-custom-dashboard-config-json) for more information on customized loading behaviour! +- Optional: `-n` or `--namedashboard` specifies the file name and path for the generated dashboard HTML. +- Default: dashboard name is **robot_dashboard_YYYYMMDD-HHMMSS.html**. + +### Set a custom HTML title +```bash +robotdashboard -t "My Cool Title" +``` +- Optional: `-t` or `--dashboardtitle` sets a custom HTML title for the dashboard. +- Default: title is **Robot Framework Dashboard - YYYY-MM-DD HH:MM:SS**. +- The title also appears in the navigation bar of the dashboard, overriding any *Custom Title* value set in the Theme settings. +- It is also possible to combine all sections into a single unified view, see [Settings - Defaults Tab](/settings#defaults-settings-defaults-tab), for the details +- The unified title will be the same as the `-t, --dashboardtitle` argument if provided, otherwise it defaults to "Dashboard Statistics" ### Control number of runs displayed by default ```bash @@ -164,7 +176,16 @@ robotdashboard --quantity 50 - Optional: `-q` or `--quantity` sets the default number of runs shown in the dashboard on first load. - Default: value in the dashboard is 20. This can be changed in the filters. -## Advanced Options +### Use local JS and CSS dependencies +```bash +robotdashboard --offlinedependencies +robotdashboard --offlinedependencies True +``` +- Optional: `--offlinedependencies` specifies to use locally downloaded js/css files and embed them directly into the dashboard. +- By default, urls to the actual JS and CSS CDN are used. +- See [Advanced CLI & Examples](/advanced-cli-examples#offline-dependencies) for more information. + +## Log Linking ### Enable Log Linking in the dashboard ```bash @@ -186,6 +207,24 @@ robotdashboard -u true -f ./results --logurl "https://ci.example.com/build/42/lo - If `--logurl` is provided without `{run_alias}` and multiple outputs are being processed, the command will produce an error. - See [Log Linking — CI Pipelines and Hosted Logs](/log-linking.md#ci-pipelines-and-hosted-logs) for full details and examples. +## Dashboard Configuration + +### Use a JSON dashboard configuration file to set default settings +```bash +robotdashboard -j ./path/to/config.json +robotdashboard --jsonconfig default_settings.json +``` +- Optional: `-j` or `--jsonconfig` sets a JSON dashboard configuration file used on first load. +- See [Advanced CLI & Examples](/advanced-cli-examples#using-a-custom-dashboard-config-json) for more information on customized loading behaviour! + +### Force the JSON config even if local storage exists +```bash +robotdashboard -j ./path/to/config.json --forcejsonconfig +robotdashboard --jsonconfig default_settings.json --forcejsonconfig +``` +- Optional: `--forcejsonconfig` forces the use of the JSON dashboard configuration file even if local storage exists. +- See [Advanced CLI & Examples](/advanced-cli-examples#using-a-custom-dashboard-config-json) for more information on customized loading behaviour! + ### Add messages config for bundling test messages ```bash robotdashboard -m message_config.txt @@ -194,22 +233,17 @@ robotdashboard --messageconfig path/to/message_config.txt - Optional: `-m` or `--messageconfig` specifies a file containing custom messages with placeholders like `${x}` or `${y}`. - See [Advanced CLI & Examples](/advanced-cli-examples#message-config-details) for more details regarding the message config! -### Use local JS and CSS dependencies -```bash -robotdashboard --offlinedependencies -robotdashboard --offlinedependencies True -``` -- Optional: `--offlinedependencies` specifies to use locally downloaded js/css files and embed them directly into the dashboard. -- By default, urls to the actual JS and CSS CDN are used. -- See [Advanced CLI & Examples](/advanced-cli-examples#offline-dependencies) for more information. +## Server -### Disable automatic database vacuuming +### Start the dashboard server ```bash -robotdashboard --novacuum -robotdashboard --novacuum True +robotdashboard --server +robotdashboard --server default +robotdashboard -s 0.0.0.0:8543 ``` -- Optional: `--novacuum` disables automatic database vacuuming. -- Default: False. Using `--novacuum` with no value sets it to True. +- Optional: `-s` or `--server` starts the dashboard web server. +- See [Dashboard Server](/dashboard-server.md) for advanced usage. +- Docker users can bind to a specific host and port as shown. ### Disable automatic dashboard regeneration on upload/delete ```bash @@ -223,23 +257,15 @@ robotdashboard --server --noautoupdate True - Only relevant when used together with `--server`. - See [Dashboard Server](/dashboard-server.md#manual-refresh-mode-noautoupdate) for more details. -### Use a custom database class +### Enable HTTPS ```bash -robotdashboard -c ./path/to/custom_class.py -robotdashboard --databaseclass mysql.py +robotdashboard --server --ssl-certfile cert.pem --ssl-keyfile key.pem +robotdashboard -s 0.0.0.0:8543 --ssl-certfile /path/to/cert.pem --ssl-keyfile /path/to/key.pem ``` -- Optional: `-c` or `--databaseclass` specifies a custom database class implementation. -- By default, Sqlite3 is used. See [Custom Database Class](/custom-database-class.md) for more information. - -## Starting the Dashboard Server -```bash -robotdashboard --server -robotdashboard --server default -robotdashboard -s 0.0.0.0:8543 -``` -- Optional: `-s` or `--server` starts the dashboard web server. -- See [Dashboard Server](/dashboard-server.md) for advanced usage. -- Docker users can bind to a specific host and port as shown. +- Optional: `--ssl-certfile` and `--ssl-keyfile` enable HTTPS by providing paths to an SSL certificate and its matching private key. +- Both flags must be provided together; neither has any effect without the other. +- Only relevant when used together with `--server`. +- See [Dashboard Server](/dashboard-server.md) for more details. ### Deprecated options diff --git a/docs/customization.md b/docs/customization.md index 271d6a1d..fbb7ca89 100644 --- a/docs/customization.md +++ b/docs/customization.md @@ -15,7 +15,7 @@ Learn how to customize the look, behavior, and configuration of the generated da The video above walks through three examples of how you can tailor the dashboard to match your reporting needs: -### 1. The Dashboard Page +## 1. The Dashboard Page See how you can reshape the main dashboard layout by: @@ -23,17 +23,17 @@ See how you can reshape the main dashboard layout by: - reordering graphs within their sections - hiding graphs you don’t want to display - rearranging entire sections to match your preferred workflow -- it is also possible to combine all sections into a single unified view, see [Settings - General Settings (Graphs Tab)](/settings#general-settings-graphs-tab), for the details +- it is also possible to combine all sections into a single unified view, see [Settings - Defaults Tab](/settings#defaults-settings-defaults-tab), for the details - the unified title will be the same as the `-t, --dashboardtitle` [CLI argument](/basic-command-line-interface-cli.html#set-a-custom-html-title) if provided, otherwise it defaults to "Dashboard Statistics" -### 2. The Compare Page +## 2. The Compare Page Watch how the Compare page can be adjusted by: - resizing comparison charts - reorganizing the visual layout to highlight the most relevant comparisons -### 3. The Tables Page +## 3. The Tables Page The demo also shows how to adapt the Tables view by: @@ -42,12 +42,12 @@ The demo also shows how to adapt the Tables view by: These examples illustrate how flexible the configuration system is, letting you build a dashboard experience that fits your team and your use cases. -### 4. Resetting the Configuration +## 4. Resetting the Configuration At the end of the video, you’ll see how you can easily **reset all customizations** by going to the **Settings** page and restoring the defaults. This quickly brings the dashboard back to its original configuration. -### 5. Theme Colors +## 5. Theme Colors The dashboard supports custom color overrides for both light and dark modes. In the Settings modal's **Theme** tab, you can customize: @@ -62,7 +62,7 @@ Each color has a **Reset** button to restore its default value. Light and dark m See [Settings - Theme Tab](/settings#theme-settings-theme-tab) for more details. -### 6. Custom Branding (Title and Logo) +## 6. Custom Branding (Title and Logo) The **Theme** tab also lets you personalize the navigation bar with your own branding: @@ -72,7 +72,7 @@ The **Theme** tab also lets you personalize the navigation bar with your own bra Both settings take effect immediately and persist across page reloads. -### 7. Responsive Menu Bar +## 7. Responsive Menu Bar The navigation bar automatically adapts to any screen width — no manual configuration required: @@ -83,7 +83,7 @@ The navigation bar automatically adapts to any screen width — no manual config This behavior is fully automatic and requires no action from the user. -### 6. Viewing (and Editing) the JSON Configuration +## 8. Viewing (and Editing) the JSON Configuration You can directly inspect the full configuration—exactly as the UI generates it—by opening the `view` key in the JSON output. This layout metadata is produced using **[GridStack](https://www.npmjs.com/package/gridstack/v/12.2.1)**. @@ -91,4 +91,36 @@ This layout metadata is produced using **[GridStack](https://www.npmjs.com/packa > ⚠️ Manually editing this JSON can be challenging because GridStack uses nested layout structures, coordinates, and sizing metadata. > It’s recommended to adjust your layout through the UI unless you know the GridStack format well. -These examples illustrate how flexible the configuration system is, letting you build a dashboard experience that fits your team and your use cases. \ No newline at end of file +These examples illustrate how flexible the configuration system is, letting you build a dashboard experience that fits your team and your use cases. + +## 9. Stat Widgets + +Stat widgets display a single KPI value (executed runs, failed tests, etc.) as a compact tile you can add to any dashboard section grid — both in regular dashboard mode and in [Unified View](/settings#defaults-settings-defaults-tab). + +To add a stat widget: + +1. Enter **Customize view** mode. +2. Click the **"+ Add stat widget"** tile that appears at the bottom of the target grid. +3. In the popup, choose the **statistic** to display and optionally pick a **text color** and **background color**. +4. Click **Add** — the widget is placed in the grid and can be dragged or resized like any other graph. +5. Click **Save** to persist the layout to localStorage. + +To remove a stat widget, enter Customize view mode and click the **✕** button in its top-right corner. + +Stat widgets are stored in localStorage and survive page reloads. + +## 10. Custom Section Dividers + +Custom section dividers are full-width horizontal bars you can place anywhere in the **Unified View** grid as visual separators or group headers. They are only available when [Unified View](/settings#defaults-settings-defaults-tab) is active. + +To add a section divider: + +1. Enter **Customize view** mode. +2. Click the **"+ Add custom section"** tile at the bottom of the unified grid. +3. In the popup, enter a **title** (up to 60 characters) and optionally choose a **text color** and **background color**. +4. Click **Add** — the divider spans the full grid width and can be dragged to any row. +5. Click **Save** to persist the layout to localStorage. + +To remove a divider, enter Customize view mode and click the **✕** button on the right side of the bar. + +Section dividers are stored in localStorage and survive page reloads. \ No newline at end of file diff --git a/docs/dashboard-server.md b/docs/dashboard-server.md index 8edf33ee..11c9d028 100644 --- a/docs/dashboard-server.md +++ b/docs/dashboard-server.md @@ -146,10 +146,10 @@ The admin page supports four methods for adding test results: | Method | Description | |--------|-------------| -| **By Absolute Path** | Provide the full path to an `output.xml` on the server filesystem. Optionally add run tags and a version label. | -| **By XML Data** | Paste raw `output.xml` content directly into a text area. Supports run tags, alias, and version label. | -| **By Folder Path** | Provide a folder path; the server recursively scans for `*output*.xml` files. Supports run tags and version label. | -| **By File Upload** | Upload an `output.xml` file directly. Supports run tags and version label. Gzip-compressed files (`.gz`/`.gzip`) are automatically decompressed. | +| **By Absolute Path** | Provide the full path to an `output.xml` on the server filesystem. Optionally add run tags, a version label, and custom filters. | +| **By XML Data** | Paste raw `output.xml` content directly into a text area. Supports run tags, alias, version label, and custom filters. | +| **By Folder Path** | Provide a folder path; the server recursively scans for `*output*.xml` files. Supports run tags, version label, and custom filters. | +| **By File Upload** | Upload an `output.xml` file directly. Supports run tags, version label, and custom filters. Gzip-compressed files (`.gz`/`.gzip`) are automatically decompressed. | ### Removing Outputs diff --git a/docs/filtering.md b/docs/filtering.md index 742c9425..0598e562 100644 --- a/docs/filtering.md +++ b/docs/filtering.md @@ -79,7 +79,17 @@ Global filters are applied to the entire dashboard, affecting all sections and g Metadata Environment Staging ``` -#### 7. Amount +#### 7. Custom Filters + +- Only visible when at least one run has custom filter data attached (added via `--customfilters` at import time or via the server/listener). +- Each unique **key** from the `key=value` pairs becomes its own filter dropdown. +- **All** (ticked by default) means no filter is applied for that dimension. +- **None** covers runs that have no value stored for that key. +- Use the **Mode** dropdown to control matching: **OR** (default), **AND**, or **NOT**. +- A dot next to the label indicates the filter is active. +- See [Advanced CLI & Examples](/advanced-cli-examples#custom-filters) for how to attach custom filter data to runs. + +#### 8. Amount - After all other filters have been applied, limits the dashboard to the **most recent X runs**. - Use **All Runs** to set the value to the total number of runs currently matching the other filters. @@ -131,6 +141,7 @@ The **Merge Profiles** button (in the Filters modal header) opens a dedicated mo |---|---| | **Run Tags** / **Versions** | Union of all checked entries (OR) | | **Use OR Tags** | OR wins (more permissive) | +| **Custom Filters** | Union of all checked entries per dimension (OR) | | **From Date / Time** | The earlier value is kept (widest horizon) | | **To Date / Time** | The later value is kept (widest horizon) | | **Amount** | The larger value is kept | @@ -180,6 +191,7 @@ The **Tables** page allows for detailed inspection of raw test data and uses the - Versions - From / To Date & Time - Metadata +- Custom Filters - Amount > These filters let you zoom into specific runs, suites, tests, or keywords for precise analysis of raw data in the tables. diff --git a/docs/listener-integration.md b/docs/listener-integration.md index 5e569735..21f5b619 100644 --- a/docs/listener-integration.md +++ b/docs/listener-integration.md @@ -93,11 +93,12 @@ The listener supports the following arguments: | `sslverify` | SSL certificate verification for HTTPS: `true` (default), `false` (skip verification for self-signed certs), or a path to a CA bundle file | | `limit` | Maximum number of runs stored in the database (older runs will be auto-deleted, based on the order in the database) | | `output` | Required only when using Pabot **with a custom output.xml name** | +| `customfilters` | Custom filter key=value pairs (colon-separated, e.g. `key=val:key2=val2`) — creates filterable dropdowns in the dashboard per key | **Example with all options** ```bash -robot --listener robotdashboardlistener.py:tags=dev1,dev2:version=v2.0:host=127.0.0.2:port=8888:protocol=https:sslverify=false:limit=100:uploadlog=true tests.robot +robot --listener robotdashboardlistener.py:tags=dev1,dev2:version=v2.0:host=127.0.0.2:port=8888:protocol=https:sslverify=false:limit=100:uploadlog=true:customfilters=Environment=staging:ComponentA=2.0 tests.robot ``` ## Using the Listener with Pabot @@ -254,9 +255,10 @@ The arguments mirror those of `robotdashboardlistener.py`: | `--protocol` | Protocol to use when connecting to the server: `http` or `https` (default: `http`) | | `--sslverify` | SSL certificate verification for HTTPS: `true` (default), `false` (skip verification for self-signed certs), or a path to a CA bundle file | | `--limit` | Maximum number of runs stored in the database (older runs will be auto-deleted) | +| `--customfilters` | Custom filter key=value pairs (colon-separated, e.g. `key=val:key2=val2`) — creates filterable dropdowns in the dashboard per key | **Example with all options** ```bash -python robotdashboardscript.py --output path/to/output.xml --log path/to/log.html --tags dev1,dev2 --version v2.0 --host 127.0.0.2 --port 8888 --protocol https --sslverify false --limit 100 +python robotdashboardscript.py --output path/to/output.xml --log path/to/log.html --tags dev1,dev2 --version v2.0 --host 127.0.0.2 --port 8888 --protocol https --sslverify false --limit 100 --customfilters "Environment=staging:ComponentA=2.0" ``` diff --git a/docs/settings.md b/docs/settings.md index a9e53fd7..014f6776 100644 --- a/docs/settings.md +++ b/docs/settings.md @@ -8,13 +8,15 @@ RobotFramework Dashboard includes a fully customizable configuration system that ## General -The settings modal is divided into **five tabs**: +The settings modal is divided into **seven tabs**: -1. **Graphs** – general dashboard and chart behavior -2. **Keywords** – which keyword libraries appear in keyword graphs -3. **Overview** – controls for the Overview page layout and toggles -4. **Theme** – custom color overrides for light and dark mode, plus custom title and logo branding -5. **JSON** – direct editing of the full JSON config for advanced users +1. **Appearance** – chart visual appearance (legends, axes, animations, bar style) +2. **Labels & Time** – run label format and timestamp display +3. **Defaults** – default dashboard behavior and initial selections +4. **Keywords** – which keyword libraries appear in keyword graphs +5. **Overview** – controls for the Overview page layout and toggles +6. **Theme** – custom color overrides for light and dark mode, plus custom title and logo branding +7. **JSON** – direct editing of the full JSON config for advanced users ## Theme Toggle @@ -22,34 +24,57 @@ The dashboard can be displayed in **light mode** or **dark mode**. This setting is applied globally across all dashboard pages and graphs. This can be set through the sun/moon icon in the menu bar. -## General Settings (Graphs Tab) +## Appearance Settings (Appearance Tab) -The **Graphs** tab contains the core configuration options for all charts in the dashboard. These settings influence how the dashboard is generated and how graphs are rendered. +The **Appearance** tab controls the visual style of charts across the dashboard. ### Details | Setting | Description | |--------|-------------| -| **Unified Dashboard Sections** | Show all dashboard sections in a single unified view. (Instead of run/suite/test/keyword separate) | | **Display Legends** | Show or hide graph legends. Useful to disable this when graphs contain many series. | | **Display Axis Titles** | Shows axis labels (e.g., *Run Time*, *Pass/Fail Count*). Disable for a cleaner look. | -| **Display Run Start/Alias Labels On Axes** | Enables labels directly on graph axes. Disable for a cleaner look. | -| **Run Label Display** | Controls which label is used to identify runs across graphs, tooltips, axes, and comparison selects. Three options are available: **Run Start** (default) — uses the raw `run_start` timestamp; **Alias** — uses the alias derived from the output filename (see [Aliases](/advanced-cli-examples#aliases-for-clean-dashboard-identification)); **Run Name** — uses the Robot Framework suite name recorded in the output file. When multiple runs share the same name, a numeric suffix is appended automatically (e.g. *Tests*, *Tests 2*, *Tests 3*). | -| **Display Prefixes** | Shows or hides the `project_` prefix text on Overview page tags. | -| **Display Milliseconds Run Start Labels** | Adds millisecond precision to run_start timestamps. | | **Display Drawing Animations** | Enables animated graph rendering. | | **Animation Duration (Milliseconds)** | Length of animation, e.g. `1500` ms. | | **Bar Graph Edge Rounding (Pixels)** | Controls rounding of bar edges (e.g., `0` = square, `8` = softer). | + +### Saving Settings + +- Press **Close** or click outside the modal -> **settings are saved automatically** + +## Labels & Time Settings (Labels & Time Tab) + +The **Labels & Time** tab controls how runs are labelled across the dashboard and how timestamps are displayed. + +### Details + +| Setting | Description | +|--------|-------------| +| **Display Run Start/Alias Labels On Axes** | Enables labels directly on graph axes. Disable for a cleaner look. | +| **Run Label Display** | Controls which label is used to identify runs across graphs, tooltips, axes, and comparison selects. Three options are available: **Run Start** (default) — uses the raw `run_start` timestamp; **Alias** — uses the alias derived from the output filename (see [Aliases](/advanced-cli-examples#aliases-for-clean-dashboard-identification)); **Run Name** — uses the Robot Framework suite name recorded in the output file. When multiple runs share the same name, a numeric suffix is appended automatically (e.g. *Tests*, *Tests 2*, *Tests 3*). | +| **Display Milliseconds Run Start Labels** | Adds millisecond precision to run_start timestamps. | | **Display Timezone Offsets** | Show or hide the timezone offset suffix (e.g. `+02:00`) appended to `run_start` timestamps in graphs and tables. Only has a visible effect on runs that have a stored timezone offset. Runs without an offset are unchanged. | | **Convert Timestamps to Local Timezone** | Converts stored `run_start` timestamps from their recorded timezone to the **viewer's browser timezone**. Only applies to runs that have a stored timezone offset — runs without an offset are left unchanged. Useful when runs were recorded in a different timezone than the person viewing the dashboard. | + +### Saving Settings + +- Press **Close** or click outside the modal -> **settings are saved automatically** + +## Defaults Settings (Defaults Tab) + +The **Defaults** tab controls initial dashboard behavior and default graph selections. + +### Details + +| Setting | Description | +|--------|-------------| +| **Unified Dashboard Sections** | Show all dashboard sections in a single unified view (instead of separate run/suite/test/keyword sections). | | **Suite Statistics – Default suite selection (dropdown)** | Selects which suite(s) are shown by default in the Suite Statistics tab. Options: `All Suites Separate`, `All Suites Combined`, or any individual suite. If the selected suite is removed from the data, the first available suite is used automatically. | | **Test Statistics – Default suite selection (dropdown)** | Selects which suite is shown by default in the Test Statistics tab. Options: `All` or any individual suite. If the selected suite is removed from the data, the first available suite is used automatically. | -| **Test Statistics – Load all suites by default** | When enabled (disabled by default) then the figures in the *Test Statistics* tab are generated from all suites, otherwise from the selected one only. This can impact the response time depending on the number of suites within the dashboard. | ### Saving Settings - Press **Close** or click outside the modal -> **settings are saved automatically** -- No need to manually apply changes for the **Graphs** tab ## Keyword Settings (Keywords Tab) diff --git a/docs/tabs-pages.md b/docs/tabs-pages.md index 4b808e12..f7b4f931 100644 --- a/docs/tabs-pages.md +++ b/docs/tabs-pages.md @@ -19,7 +19,7 @@ For a more in depth explanation, hover over the "i" icons in the Overview Statis The Dashboard page offers rich, interactive visualizations for a detailed analysis of test results. Graphs are available at four levels—runs, suites, tests, and keywords—allowing teams to track performance, detect flaky tests, and monitor trends over time. The layout is fully customizable (see [Customization](customization.md)). You can drag and drop graphs and sections to create your preferred view. Most graphs support multiple display modes, including timeline, percentage, bar, donut, and advanced types like boxplots and heatmaps. Each graph also provides detailed popups to explain what the view represents and how the data is calculated (see [Graphs & Tables](graphs-tables.md)). ### Unified Mode -The Dashboard supports a **Unified Mode** that combines all four sections (run, suite, test, keyword) into a single scrollable view instead of separate tabbed sections. This can be enabled via [Settings - Graphs Tab](/settings#general-settings-graphs-tab) using the **Unified Dashboard Sections** toggle. +The Dashboard supports a **Unified Mode** that combines all four sections (run, suite, test, keyword) into a single scrollable view instead of separate tabbed sections. This can be enabled via [Settings - Defaults Tab](/settings#defaults-settings-defaults-tab) using the **Unified Dashboard Sections** toggle. In Unified Mode: - All graphs from all sections are shown on one page From d76604d1a3847de176adb8f6de79748833be3521 Mon Sep 17 00:00:00 2001 From: Tim de Groot Date: Mon, 25 May 2026 22:00:33 +0200 Subject: [PATCH 3/6] feat: unify test execution by changing to suite-level parallelism and updating test setups --- .github/skills/robotframework-tests.md | 6 +++--- scripts/robot-tests.bat | 2 +- scripts/robot-tests.sh | 2 +- tests/robot/resources/keywords/general-keywords.resource | 2 +- tests/robot/testsuites/01_database.robot | 6 ++++-- tests/robot/testsuites/02_overview.robot | 8 ++++---- tests/robot/testsuites/03_dashboard.robot | 8 ++++---- tests/robot/testsuites/04_compare.robot | 8 ++++---- tests/robot/testsuites/05_tables.robot | 8 ++++---- tests/robot/testsuites/06_filters.robot | 8 ++++---- tests/robot/testsuites/07_settings.robot | 8 ++++---- 11 files changed, 34 insertions(+), 32 deletions(-) diff --git a/.github/skills/robotframework-tests.md b/.github/skills/robotframework-tests.md index d605fe17..d83d0f10 100644 --- a/.github/skills/robotframework-tests.md +++ b/.github/skills/robotframework-tests.md @@ -14,17 +14,17 @@ All tests are **Robot Framework acceptance tests** run with **pabot**. Tests liv ```bash # Windows -pabot --pabotlib --testlevelsplit --artifacts png,jpg --artifactsinsubfolders --processes 2 -d results .\tests\robot\testsuites\*.robot +pabot --pabotlib --suitelevelsplit --artifacts png,jpg --artifactsinsubfolders --processes 2 -d results .\tests\robot\testsuites\*.robot # Linux / macOS -pabot --pabotlib --testlevelsplit --artifacts png,jpg --artifactsinsubfolders --processes 2 -d results tests/robot/testsuites/*.robot +pabot --pabotlib --suitelevelsplit --artifacts png,jpg --artifactsinsubfolders --processes 2 -d results tests/robot/testsuites/*.robot ``` Convenience scripts: `scripts/robot-tests.bat` and `scripts/robot-tests.sh`. Key pabot flags: - `--pabotlib` — starts the pabot shared library server (required for cross-process locks used by the index counter) -- `--testlevelsplit` — each individual test case runs in parallel, not each suite +- `--suitelevelsplit` — each suite runs as one unit in parallel; all tests within a suite run sequentially in the same process - `--artifacts png,jpg --artifactsinsubfolders` — collects screenshots from each pabot worker's output dir - `-d results` — all output goes to `results/` diff --git a/scripts/robot-tests.bat b/scripts/robot-tests.bat index 25011218..442f193f 100644 --- a/scripts/robot-tests.bat +++ b/scripts/robot-tests.bat @@ -1,3 +1,3 @@ @echo off REM Run all Robot Framework tests in tests/robot/testsuites/ -pabot --pabotlib --testlevelsplit --artifacts png,jpg --artifactsinsubfolders --processes 2 -d results .\tests\robot\testsuites\*.robot +pabot --pabotlib --suitelevelsplit --artifacts png,jpg --artifactsinsubfolders --processes 2 -d results .\tests\robot\testsuites\*.robot diff --git a/scripts/robot-tests.sh b/scripts/robot-tests.sh index a2cd3328..9bfa1f16 100644 --- a/scripts/robot-tests.sh +++ b/scripts/robot-tests.sh @@ -4,7 +4,7 @@ set -e # Run all Robot Framework tests in tests/robot/testsuites/ pabot \ --pabotlib \ - --testlevelsplit \ + --suitelevelsplit \ --artifacts png,jpg \ --artifactsinsubfolders \ --processes 2 \ diff --git a/tests/robot/resources/keywords/general-keywords.resource b/tests/robot/resources/keywords/general-keywords.resource index 64e76c60..f65ad201 100644 --- a/tests/robot/resources/keywords/general-keywords.resource +++ b/tests/robot/resources/keywords/general-keywords.resource @@ -23,7 +23,7 @@ Get Dashboard Index Generate Dashboard ${index} Get Dashboard Index Release Lock name=dashboard_index - VAR ${DASHBOARD_INDEX} ${index} scope=test + VAR ${DASHBOARD_INDEX} ${index} scope=SUITE ${files} Catenate SEPARATOR=${SPACE} ... -o ${CURDIR}/../outputs/output-20250313-002134.xml:prod:project_1:version_1.0 ... -o ${CURDIR}/../outputs/output-20250313-002151.xml:dev:project_1:version_1.0 diff --git a/tests/robot/testsuites/01_database.robot b/tests/robot/testsuites/01_database.robot index cdae103c..9c231b46 100644 --- a/tests/robot/testsuites/01_database.robot +++ b/tests/robot/testsuites/01_database.robot @@ -4,8 +4,10 @@ Documentation This testsuite covers the generated database of robotdashboard Resource ../resources/keywords/database-keywords.resource Resource ../resources/keywords/general-keywords.resource -Test Setup Run Keywords Generate Dashboard Create Database Connection -Test Teardown Run Keywords Close Database Connection Remove Database And Dashboard With Index +Suite Setup Generate Dashboard +Suite Teardown Remove Database And Dashboard With Index +Test Setup Create Database Connection +Test Teardown Close Database Connection *** Test Cases *** diff --git a/tests/robot/testsuites/02_overview.robot b/tests/robot/testsuites/02_overview.robot index cc61f678..026d7904 100644 --- a/tests/robot/testsuites/02_overview.robot +++ b/tests/robot/testsuites/02_overview.robot @@ -5,10 +5,10 @@ Documentation This testsuite covers the generated HTML dashboard of robotdash Resource ../resources/keywords/dashboard-keywords.resource Resource ../resources/keywords/general-keywords.resource -Suite Setup Start Browser -Suite Teardown Stop Browser -Test Setup Run Keywords Generate Dashboard Open Dashboard -Test Teardown Run Keywords Close Dashboard Remove Database And Dashboard With Index +Suite Setup Run Keywords Start Browser Generate Dashboard +Suite Teardown Run Keywords Stop Browser Remove Database And Dashboard With Index +Test Setup Open Dashboard +Test Teardown Close Dashboard *** Test Cases *** diff --git a/tests/robot/testsuites/03_dashboard.robot b/tests/robot/testsuites/03_dashboard.robot index f5742460..1741b65f 100644 --- a/tests/robot/testsuites/03_dashboard.robot +++ b/tests/robot/testsuites/03_dashboard.robot @@ -4,10 +4,10 @@ Documentation This testsuite covers the generated HTML dashboard of robotdash Resource ../resources/keywords/dashboard-keywords.resource Resource ../resources/keywords/general-keywords.resource -Suite Setup Start Browser -Suite Teardown Close Browser -Test Setup Run Keywords Generate Dashboard Open Dashboard -Test Teardown Run Keywords Close Dashboard Remove Database And Dashboard With Index +Suite Setup Run Keywords Start Browser Generate Dashboard +Suite Teardown Run Keywords Close Browser Remove Database And Dashboard With Index +Test Setup Open Dashboard +Test Teardown Close Dashboard *** Test Cases *** diff --git a/tests/robot/testsuites/04_compare.robot b/tests/robot/testsuites/04_compare.robot index a3902671..e0400639 100644 --- a/tests/robot/testsuites/04_compare.robot +++ b/tests/robot/testsuites/04_compare.robot @@ -4,10 +4,10 @@ Documentation This testsuite covers the generated HTML dashboard of robotdash Resource ../resources/keywords/dashboard-keywords.resource Resource ../resources/keywords/general-keywords.resource -Suite Setup Start Browser -Suite Teardown Close Browser -Test Setup Run Keywords Generate Dashboard Open Dashboard -Test Teardown Run Keywords Close Dashboard Remove Database And Dashboard With Index +Suite Setup Run Keywords Start Browser Generate Dashboard +Suite Teardown Run Keywords Close Browser Remove Database And Dashboard With Index +Test Setup Open Dashboard +Test Teardown Close Dashboard *** Test Cases *** diff --git a/tests/robot/testsuites/05_tables.robot b/tests/robot/testsuites/05_tables.robot index 92c6bd4c..ce56a773 100644 --- a/tests/robot/testsuites/05_tables.robot +++ b/tests/robot/testsuites/05_tables.robot @@ -4,10 +4,10 @@ Documentation This testsuite covers the generated HTML dashboard of robotdash Resource ../resources/keywords/dashboard-keywords.resource Resource ../resources/keywords/general-keywords.resource -Suite Setup Start Browser -Suite Teardown Close Browser -Test Setup Run Keywords Generate Dashboard Open Dashboard -Test Teardown Run Keywords Close Dashboard Remove Database And Dashboard With Index +Suite Setup Run Keywords Start Browser Generate Dashboard +Suite Teardown Run Keywords Close Browser Remove Database And Dashboard With Index +Test Setup Open Dashboard +Test Teardown Close Dashboard *** Test Cases *** diff --git a/tests/robot/testsuites/06_filters.robot b/tests/robot/testsuites/06_filters.robot index 2b3f2ffd..634466f5 100644 --- a/tests/robot/testsuites/06_filters.robot +++ b/tests/robot/testsuites/06_filters.robot @@ -4,10 +4,10 @@ Documentation This testsuite covers the generated HTML dashboard of robotdash Resource ../resources/keywords/dashboard-keywords.resource Resource ../resources/keywords/general-keywords.resource -Suite Setup Start Browser -Suite Teardown Close Browser -Test Setup Run Keywords Generate Dashboard Open Dashboard -Test Teardown Run Keywords Close Dashboard Remove Database And Dashboard With Index +Suite Setup Run Keywords Start Browser Generate Dashboard +Suite Teardown Run Keywords Close Browser Remove Database And Dashboard With Index +Test Setup Open Dashboard +Test Teardown Close Dashboard *** Test Cases *** diff --git a/tests/robot/testsuites/07_settings.robot b/tests/robot/testsuites/07_settings.robot index 6114f294..52d15e35 100644 --- a/tests/robot/testsuites/07_settings.robot +++ b/tests/robot/testsuites/07_settings.robot @@ -4,10 +4,10 @@ Documentation This testsuite covers the generated HTML dashboard of robotdash Resource ../resources/keywords/dashboard-keywords.resource Resource ../resources/keywords/general-keywords.resource -Suite Setup Start Browser -Suite Teardown Close Browser -Test Setup Run Keywords Generate Dashboard Open Dashboard -Test Teardown Run Keywords Close Dashboard Remove Database And Dashboard With Index +Suite Setup Run Keywords Start Browser Generate Dashboard +Suite Teardown Run Keywords Close Browser Remove Database And Dashboard With Index +Test Setup Open Dashboard +Test Teardown Close Dashboard *** Test Cases *** From bcba6ed9bfa20ce0ffa5642f62692cf5d9ffb194 Mon Sep 17 00:00:00 2001 From: Tim de Groot Date: Mon, 25 May 2026 22:03:56 +0200 Subject: [PATCH 4/6] feat: remove suite-level split option from pabot commands for unified test execution --- .github/skills/robotframework-tests.md | 6 +++--- scripts/robot-tests.bat | 2 +- scripts/robot-tests.sh | 1 - 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/.github/skills/robotframework-tests.md b/.github/skills/robotframework-tests.md index d83d0f10..0400cc68 100644 --- a/.github/skills/robotframework-tests.md +++ b/.github/skills/robotframework-tests.md @@ -14,17 +14,17 @@ All tests are **Robot Framework acceptance tests** run with **pabot**. Tests liv ```bash # Windows -pabot --pabotlib --suitelevelsplit --artifacts png,jpg --artifactsinsubfolders --processes 2 -d results .\tests\robot\testsuites\*.robot +pabot --pabotlib --artifacts png,jpg --artifactsinsubfolders --processes 2 -d results .\tests\robot\testsuites\*.robot # Linux / macOS -pabot --pabotlib --suitelevelsplit --artifacts png,jpg --artifactsinsubfolders --processes 2 -d results tests/robot/testsuites/*.robot +pabot --pabotlib --artifacts png,jpg --artifactsinsubfolders --processes 2 -d results tests/robot/testsuites/*.robot ``` Convenience scripts: `scripts/robot-tests.bat` and `scripts/robot-tests.sh`. Key pabot flags: - `--pabotlib` — starts the pabot shared library server (required for cross-process locks used by the index counter) -- `--suitelevelsplit` — each suite runs as one unit in parallel; all tests within a suite run sequentially in the same process +- no `--testlevelsplit` to make sure each suite runs as one unit in parallel; all tests within a suite run sequentially in the same process - `--artifacts png,jpg --artifactsinsubfolders` — collects screenshots from each pabot worker's output dir - `-d results` — all output goes to `results/` diff --git a/scripts/robot-tests.bat b/scripts/robot-tests.bat index 442f193f..b63c5a3e 100644 --- a/scripts/robot-tests.bat +++ b/scripts/robot-tests.bat @@ -1,3 +1,3 @@ @echo off REM Run all Robot Framework tests in tests/robot/testsuites/ -pabot --pabotlib --suitelevelsplit --artifacts png,jpg --artifactsinsubfolders --processes 2 -d results .\tests\robot\testsuites\*.robot +pabot --pabotlib --artifacts png,jpg --artifactsinsubfolders --processes 2 -d results .\tests\robot\testsuites\*.robot diff --git a/scripts/robot-tests.sh b/scripts/robot-tests.sh index 9bfa1f16..4e11f9ea 100644 --- a/scripts/robot-tests.sh +++ b/scripts/robot-tests.sh @@ -4,7 +4,6 @@ set -e # Run all Robot Framework tests in tests/robot/testsuites/ pabot \ --pabotlib \ - --suitelevelsplit \ --artifacts png,jpg \ --artifactsinsubfolders \ --processes 2 \ From 0acd3e46a89e497083bd72b564baecc4fba16553 Mon Sep 17 00:00:00 2001 From: Tim de Groot Date: Mon, 25 May 2026 22:12:20 +0200 Subject: [PATCH 5/6] fix: update dashboard index creation to use suite name instead of test name --- tests/robot/resources/keywords/general-keywords.resource | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/robot/resources/keywords/general-keywords.resource b/tests/robot/resources/keywords/general-keywords.resource index f65ad201..f6890b7a 100644 --- a/tests/robot/resources/keywords/general-keywords.resource +++ b/tests/robot/resources/keywords/general-keywords.resource @@ -10,14 +10,14 @@ Get Dashboard Index Acquire Lock name=dashboard_index ${exists} Run Keyword And Return Status Should Exist path=index.txt IF not ${exists} - Create File path=index.txt content=1:${TEST_NAME} + Create File path=index.txt content=1:${SUITE_NAME} RETURN ${1} END ${index} Get File path=index.txt ${index} Split String string=${index} separator=: ${index} Convert To Integer ${index}[0] ${index} Evaluate ${index} + 1 - Create File path=index.txt content=${index}:${TEST_NAME} + Create File path=index.txt content=${index}:${SUITE_NAME} RETURN ${index} Generate Dashboard From 8905f0d984a0f26da41a0d34aaeeb864a7829a55 Mon Sep 17 00:00:00 2001 From: Tim de Groot Date: Mon, 25 May 2026 22:22:53 +0200 Subject: [PATCH 6/6] feat: unify test execution by enabling test-level parallelism and updating test setups across all test suites --- .github/skills/robotframework-tests.md | 6 +++--- scripts/robot-tests.bat | 2 +- scripts/robot-tests.sh | 1 + .../resources/keywords/general-keywords.resource | 6 +++--- tests/robot/testsuites/01_database.robot | 6 ++---- tests/robot/testsuites/02_overview.robot | 8 ++++---- tests/robot/testsuites/03_dashboard.robot | 8 ++++---- tests/robot/testsuites/04_compare.robot | 8 ++++---- tests/robot/testsuites/05_tables.robot | 8 ++++---- tests/robot/testsuites/06_filters.robot | 8 ++++---- tests/robot/testsuites/07_settings.robot | 11 ++++++----- 11 files changed, 36 insertions(+), 36 deletions(-) diff --git a/.github/skills/robotframework-tests.md b/.github/skills/robotframework-tests.md index 0400cc68..d605fe17 100644 --- a/.github/skills/robotframework-tests.md +++ b/.github/skills/robotframework-tests.md @@ -14,17 +14,17 @@ All tests are **Robot Framework acceptance tests** run with **pabot**. Tests liv ```bash # Windows -pabot --pabotlib --artifacts png,jpg --artifactsinsubfolders --processes 2 -d results .\tests\robot\testsuites\*.robot +pabot --pabotlib --testlevelsplit --artifacts png,jpg --artifactsinsubfolders --processes 2 -d results .\tests\robot\testsuites\*.robot # Linux / macOS -pabot --pabotlib --artifacts png,jpg --artifactsinsubfolders --processes 2 -d results tests/robot/testsuites/*.robot +pabot --pabotlib --testlevelsplit --artifacts png,jpg --artifactsinsubfolders --processes 2 -d results tests/robot/testsuites/*.robot ``` Convenience scripts: `scripts/robot-tests.bat` and `scripts/robot-tests.sh`. Key pabot flags: - `--pabotlib` — starts the pabot shared library server (required for cross-process locks used by the index counter) -- no `--testlevelsplit` to make sure each suite runs as one unit in parallel; all tests within a suite run sequentially in the same process +- `--testlevelsplit` — each individual test case runs in parallel, not each suite - `--artifacts png,jpg --artifactsinsubfolders` — collects screenshots from each pabot worker's output dir - `-d results` — all output goes to `results/` diff --git a/scripts/robot-tests.bat b/scripts/robot-tests.bat index b63c5a3e..25011218 100644 --- a/scripts/robot-tests.bat +++ b/scripts/robot-tests.bat @@ -1,3 +1,3 @@ @echo off REM Run all Robot Framework tests in tests/robot/testsuites/ -pabot --pabotlib --artifacts png,jpg --artifactsinsubfolders --processes 2 -d results .\tests\robot\testsuites\*.robot +pabot --pabotlib --testlevelsplit --artifacts png,jpg --artifactsinsubfolders --processes 2 -d results .\tests\robot\testsuites\*.robot diff --git a/scripts/robot-tests.sh b/scripts/robot-tests.sh index 4e11f9ea..a2cd3328 100644 --- a/scripts/robot-tests.sh +++ b/scripts/robot-tests.sh @@ -4,6 +4,7 @@ set -e # Run all Robot Framework tests in tests/robot/testsuites/ pabot \ --pabotlib \ + --testlevelsplit \ --artifacts png,jpg \ --artifactsinsubfolders \ --processes 2 \ diff --git a/tests/robot/resources/keywords/general-keywords.resource b/tests/robot/resources/keywords/general-keywords.resource index f6890b7a..64e76c60 100644 --- a/tests/robot/resources/keywords/general-keywords.resource +++ b/tests/robot/resources/keywords/general-keywords.resource @@ -10,20 +10,20 @@ Get Dashboard Index Acquire Lock name=dashboard_index ${exists} Run Keyword And Return Status Should Exist path=index.txt IF not ${exists} - Create File path=index.txt content=1:${SUITE_NAME} + Create File path=index.txt content=1:${TEST_NAME} RETURN ${1} END ${index} Get File path=index.txt ${index} Split String string=${index} separator=: ${index} Convert To Integer ${index}[0] ${index} Evaluate ${index} + 1 - Create File path=index.txt content=${index}:${SUITE_NAME} + Create File path=index.txt content=${index}:${TEST_NAME} RETURN ${index} Generate Dashboard ${index} Get Dashboard Index Release Lock name=dashboard_index - VAR ${DASHBOARD_INDEX} ${index} scope=SUITE + VAR ${DASHBOARD_INDEX} ${index} scope=test ${files} Catenate SEPARATOR=${SPACE} ... -o ${CURDIR}/../outputs/output-20250313-002134.xml:prod:project_1:version_1.0 ... -o ${CURDIR}/../outputs/output-20250313-002151.xml:dev:project_1:version_1.0 diff --git a/tests/robot/testsuites/01_database.robot b/tests/robot/testsuites/01_database.robot index 9c231b46..cdae103c 100644 --- a/tests/robot/testsuites/01_database.robot +++ b/tests/robot/testsuites/01_database.robot @@ -4,10 +4,8 @@ Documentation This testsuite covers the generated database of robotdashboard Resource ../resources/keywords/database-keywords.resource Resource ../resources/keywords/general-keywords.resource -Suite Setup Generate Dashboard -Suite Teardown Remove Database And Dashboard With Index -Test Setup Create Database Connection -Test Teardown Close Database Connection +Test Setup Run Keywords Generate Dashboard Create Database Connection +Test Teardown Run Keywords Close Database Connection Remove Database And Dashboard With Index *** Test Cases *** diff --git a/tests/robot/testsuites/02_overview.robot b/tests/robot/testsuites/02_overview.robot index 026d7904..cc61f678 100644 --- a/tests/robot/testsuites/02_overview.robot +++ b/tests/robot/testsuites/02_overview.robot @@ -5,10 +5,10 @@ Documentation This testsuite covers the generated HTML dashboard of robotdash Resource ../resources/keywords/dashboard-keywords.resource Resource ../resources/keywords/general-keywords.resource -Suite Setup Run Keywords Start Browser Generate Dashboard -Suite Teardown Run Keywords Stop Browser Remove Database And Dashboard With Index -Test Setup Open Dashboard -Test Teardown Close Dashboard +Suite Setup Start Browser +Suite Teardown Stop Browser +Test Setup Run Keywords Generate Dashboard Open Dashboard +Test Teardown Run Keywords Close Dashboard Remove Database And Dashboard With Index *** Test Cases *** diff --git a/tests/robot/testsuites/03_dashboard.robot b/tests/robot/testsuites/03_dashboard.robot index 1741b65f..f5742460 100644 --- a/tests/robot/testsuites/03_dashboard.robot +++ b/tests/robot/testsuites/03_dashboard.robot @@ -4,10 +4,10 @@ Documentation This testsuite covers the generated HTML dashboard of robotdash Resource ../resources/keywords/dashboard-keywords.resource Resource ../resources/keywords/general-keywords.resource -Suite Setup Run Keywords Start Browser Generate Dashboard -Suite Teardown Run Keywords Close Browser Remove Database And Dashboard With Index -Test Setup Open Dashboard -Test Teardown Close Dashboard +Suite Setup Start Browser +Suite Teardown Close Browser +Test Setup Run Keywords Generate Dashboard Open Dashboard +Test Teardown Run Keywords Close Dashboard Remove Database And Dashboard With Index *** Test Cases *** diff --git a/tests/robot/testsuites/04_compare.robot b/tests/robot/testsuites/04_compare.robot index e0400639..a3902671 100644 --- a/tests/robot/testsuites/04_compare.robot +++ b/tests/robot/testsuites/04_compare.robot @@ -4,10 +4,10 @@ Documentation This testsuite covers the generated HTML dashboard of robotdash Resource ../resources/keywords/dashboard-keywords.resource Resource ../resources/keywords/general-keywords.resource -Suite Setup Run Keywords Start Browser Generate Dashboard -Suite Teardown Run Keywords Close Browser Remove Database And Dashboard With Index -Test Setup Open Dashboard -Test Teardown Close Dashboard +Suite Setup Start Browser +Suite Teardown Close Browser +Test Setup Run Keywords Generate Dashboard Open Dashboard +Test Teardown Run Keywords Close Dashboard Remove Database And Dashboard With Index *** Test Cases *** diff --git a/tests/robot/testsuites/05_tables.robot b/tests/robot/testsuites/05_tables.robot index ce56a773..92c6bd4c 100644 --- a/tests/robot/testsuites/05_tables.robot +++ b/tests/robot/testsuites/05_tables.robot @@ -4,10 +4,10 @@ Documentation This testsuite covers the generated HTML dashboard of robotdash Resource ../resources/keywords/dashboard-keywords.resource Resource ../resources/keywords/general-keywords.resource -Suite Setup Run Keywords Start Browser Generate Dashboard -Suite Teardown Run Keywords Close Browser Remove Database And Dashboard With Index -Test Setup Open Dashboard -Test Teardown Close Dashboard +Suite Setup Start Browser +Suite Teardown Close Browser +Test Setup Run Keywords Generate Dashboard Open Dashboard +Test Teardown Run Keywords Close Dashboard Remove Database And Dashboard With Index *** Test Cases *** diff --git a/tests/robot/testsuites/06_filters.robot b/tests/robot/testsuites/06_filters.robot index 634466f5..2b3f2ffd 100644 --- a/tests/robot/testsuites/06_filters.robot +++ b/tests/robot/testsuites/06_filters.robot @@ -4,10 +4,10 @@ Documentation This testsuite covers the generated HTML dashboard of robotdash Resource ../resources/keywords/dashboard-keywords.resource Resource ../resources/keywords/general-keywords.resource -Suite Setup Run Keywords Start Browser Generate Dashboard -Suite Teardown Run Keywords Close Browser Remove Database And Dashboard With Index -Test Setup Open Dashboard -Test Teardown Close Dashboard +Suite Setup Start Browser +Suite Teardown Close Browser +Test Setup Run Keywords Generate Dashboard Open Dashboard +Test Teardown Run Keywords Close Dashboard Remove Database And Dashboard With Index *** Test Cases *** diff --git a/tests/robot/testsuites/07_settings.robot b/tests/robot/testsuites/07_settings.robot index 52d15e35..e69f5643 100644 --- a/tests/robot/testsuites/07_settings.robot +++ b/tests/robot/testsuites/07_settings.robot @@ -4,13 +4,14 @@ Documentation This testsuite covers the generated HTML dashboard of robotdash Resource ../resources/keywords/dashboard-keywords.resource Resource ../resources/keywords/general-keywords.resource -Suite Setup Run Keywords Start Browser Generate Dashboard -Suite Teardown Run Keywords Close Browser Remove Database And Dashboard With Index -Test Setup Open Dashboard -Test Teardown Close Dashboard +Suite Setup Start Browser +Suite Teardown Close Browser +Test Setup Run Keywords Generate Dashboard Open Dashboard +Test Teardown Run Keywords Close Dashboard Remove Database And Dashboard With Index *** Test Cases *** Validate Settings Change Settings - Validate Component id=runStatisticsSection name=changedSettings folder=run + # threshold loosened to 0.01 (99% accuracy) — chart re-renders after multiple settings changes cause minor pixel variations + Validate Component id=runStatisticsSection name=changedSettings folder=run threshold=0.01