Skip to content

Post process backstop report name - #8067

Closed
srambach wants to merge 3 commits into
patternfly:mainfrom
srambach:post-process-backstop-report-name
Closed

Post process backstop report name#8067
srambach wants to merge 3 commits into
patternfly:mainfrom
srambach:post-process-backstop-report-name

Conversation

@srambach

@srambach srambach commented Jan 22, 2026

Copy link
Copy Markdown
Member

Backstop doesn't differentiate the id shown at the top of a report from the initial part of the screen capture filenames.
This PR introduces a wrapper script that changes the name at the top of the report after it's created.

Note: in testing, it works well but (probably because the html report is opened in the browser immediately after creation) you need to reload the page to see the changed name.

Summary by CodeRabbit

  • New Features

    • New test runner CLI that executes visual tests and applies post-processing.
    • Post-processing step can inject a custom report description and apply a dark-theme variant.
  • Chores

    • Test scripts updated to use the new runner.
    • Reports now use a consistent, fixed report identifier for generated outputs.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai

coderabbitai Bot commented Jan 22, 2026

Copy link
Copy Markdown
Contributor

Walkthrough

This PR removes dynamic title/description logic from backstop.js, sets module.exports.id to the constant 'pf-core', adds two runner/post-process scripts to run Backstop and inject custom descriptions into generated reports, and updates npm scripts to use the new runner.

Changes

Cohort / File(s) Summary
BackstopJS Configuration
backstop.js
Removed parsing of --desc and dynamic title/theme logic. module.exports.id changed to constant 'pf-core'.
NPM Scripts
package.json
Updated scripts to run Backstop via the new runner: backstop:testnode scripts/backstop-run.mjs test; backstop:test:darknode scripts/backstop-run.mjs test --dark.
Runner & Post-Processor
scripts/backstop-run.mjs, scripts/backstop-post-process.mjs
Added backstop-run.mjs: forwards args to BackstopJS, captures exit code, and invokes post-processor. Added backstop-post-process.mjs: locates report config.js, extracts JSONP, updates testSuite (supports --desc and --dark), and writes updated JSONP.

Sequence Diagram(s)

sequenceDiagram
    participant npm as "npm script"
    participant run as "backstop-run.mjs" 
    participant backstop as "BackstopJS CLI"
    participant post as "backstop-post-process.mjs"
    participant report as "Report Files"

    npm->>run: node scripts/backstop-run.mjs test [--dark] [--desc=...]
    run->>backstop: spawn backstop test --config='backstop.js' [--dark]
    backstop->>report: generate HTML report (including config.js)
    backstop-->>run: exit code
    run->>post: node scripts/backstop-post-process.mjs [--desc=...] [--dark]
    post->>report: read config.js (JSONP)
    post->>post: parse JSONP, update testSuite
    post->>report: write updated config.js (JSONP)
    post-->>run: exit status (warnings logged if failed)
    run-->>npm: propagate BackstopJS exit code
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Suggested reviewers

  • mcoker

Important

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

❌ Failed checks (1 error)
Check name Status Explanation Resolution
Title check ❌ Error The PR title does not follow conventional commit format with a type prefix (e.g., feat:, fix:, chore:). It lacks the required conventional commit structure. Reformat the title to follow conventional commits, e.g., 'feat: post process backstop report name' or 'chore: post process backstop report name'.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai
coderabbitai Bot requested a review from mcoker January 22, 2026 19:41
@patternfly-build

patternfly-build commented Jan 22, 2026

Copy link
Copy Markdown
Collaborator

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@scripts/backstop-post-process.mjs`:
- Around line 43-46: The JSONP parsing uses a strict regex
content.match(/^report\(([\s\S]*)\);?\s*$/) that fails if config.js has a BOM or
leading whitespace; update the code to either strip a BOM (e.g. content =
content.replace(/^\uFEFF/, '')) and then use a tolerant regex like
content.match(/^\s*report\(([\s\S]*)\);?\s*$/) or directly allow optional
BOM/whitespace in the regex (e.g.
content.match(/^(?:\uFEFF)?\s*report\(([\s\S]*)\);?\s*$/)); change the match
usage accordingly so the variable match still captures the JSON group.

In `@scripts/backstop-run.mjs`:
- Around line 32-69: The runBackstop and runPostProcessor functions currently
build shell command strings (backstopCommand and postProcessCommand) and call
execSync, which permits shell injection and breaks on Windows; update both to
use child_process.spawnSync with argument arrays: for runBackstop call
spawnSync('backstop', [...args, '--config', 'backstop.js'], { stdio:'inherit',
cwd: path.join(__dirname,'..') }) and derive success/exitCode from the returned
.status (and .error when present) instead of catching a thrown error; for
runPostProcessor call spawnSync(process.execPath or 'node',
[path.join(__dirname,'backstop-post-process.mjs'), ...args], { stdio:'inherit',
cwd: path.join(__dirname,'..') }) and similarly propagate success/exitCode —
this removes shell quoting, prevents injection, and fixes Windows quoting
issues.

Comment thread scripts/backstop-post-process.mjs
Comment thread scripts/backstop-run.mjs Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@scripts/backstop-run.mjs`:
- Around line 14-30: Update parseArguments to also handle a standalone '--desc'
token followed by the description as the next argv entry: when iterating args in
parseArguments(), check for arg === '--desc' and if so consume the next element
as customDescription (strip surrounding quotes) and skip pushing both into
backstopArgs; keep existing handling for '--desc=...' intact and ensure you
guard against '--desc' being the last arg (leave customDescription null in that
case and do not push '--desc' to backstopArgs).

Comment thread scripts/backstop-run.mjs
Comment on lines +14 to +30
function parseArguments() {
const args = process.argv.slice(2);
const backstopArgs = [];
let customDescription = null;

for (const arg of args) {
if (arg.startsWith('--desc=')) {
// Extract description and remove surrounding quotes
customDescription = arg.substring(7).replace(/^["']|["']$/g, '');
} else {
// Pass all other arguments to BackstopJS
backstopArgs.push(arg);
}
}

return { backstopArgs, customDescription };
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Support --desc passed as a separate arg to avoid leaking it to BackstopJS.
Currently only --desc=... is parsed. If users pass --desc "My report", the flag is forwarded to BackstopJS and the post-processor won’t receive the description.

🛠️ Proposed fix
 function parseArguments() {
   const args = process.argv.slice(2);
   const backstopArgs = [];
   let customDescription = null;
 
-  for (const arg of args) {
-    if (arg.startsWith('--desc=')) {
-      // Extract description and remove surrounding quotes
-      customDescription = arg.substring(7).replace(/^["']|["']$/g, '');
-    } else {
-      // Pass all other arguments to BackstopJS
-      backstopArgs.push(arg);
-    }
-  }
+  for (let i = 0; i < args.length; i++) {
+    const arg = args[i];
+
+    if (arg === '--desc') {
+      const next = args[i + 1];
+      if (!next) {
+        console.error('Error: --desc requires a value');
+        process.exit(1);
+      }
+      customDescription = next.replace(/^["']|["']$/g, '');
+      i++; // consume value
+      continue;
+    }
+
+    if (arg.startsWith('--desc=')) {
+      // Extract description and remove surrounding quotes
+      customDescription = arg.substring(7).replace(/^["']|["']$/g, '');
+    } else {
+      // Pass all other arguments to BackstopJS
+      backstopArgs.push(arg);
+    }
+  }
 
   return { backstopArgs, customDescription };
 }
🤖 Prompt for AI Agents
In `@scripts/backstop-run.mjs` around lines 14 - 30, Update parseArguments to also
handle a standalone '--desc' token followed by the description as the next argv
entry: when iterating args in parseArguments(), check for arg === '--desc' and
if so consume the next element as customDescription (strip surrounding quotes)
and skip pushing both into backstopArgs; keep existing handling for '--desc=...'
intact and ensure you guard against '--desc' being the last arg (leave
customDescription null in that case and do not push '--desc' to backstopArgs).

@srambach srambach closed this Jan 22, 2026
@srambach

Copy link
Copy Markdown
Member Author

Closing since it's more complicated than it's worth

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants