Skip to content

Commit

Permalink
Feat/1432 global scenario settings (#1539)
Browse files Browse the repository at this point in the history
  • Loading branch information
dgrebb authored Feb 1, 2024
1 parent 141938c commit 0c8ead0
Show file tree
Hide file tree
Showing 4 changed files with 126 additions and 22 deletions.
85 changes: 84 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ npm install -g backstopjs
- [Approving Changes](#approving-changes)
- [Using BackstopJS](#using-backstopjs)
- [Scenario Properties](#scenario-properties)
- [Global Scenario Properties](#global-scenario-properties)
- [Advanced Scenarios](#advanced-scenarios)
- [Developing, Bug Fixing, Contributing...](#developing-bug-fixing-contributing)
- [Troubleshooting](#troubleshooting)
Expand Down Expand Up @@ -168,7 +169,7 @@ Pass a `--filter=<image_filename_regex>` argument to promote only the test captu

### Scenario Properties

Scenario properties are described throughout this document and **processed sequentially in the following order...**
Scenario properties, [which may be global](#global-scenario-properties), are described throughout this document and **processed sequentially in the following order...**

| Property | Description |
|--------------------------|--------------------------------------------------------------------------------------------------------------------------------|
Expand Down Expand Up @@ -198,6 +199,88 @@ Scenario properties are described throughout this document and **processed seque
| `viewports` | An array of screen size objects your DOM will be tested against. This configuration will override the viewports property assigned at the config root. |
| `gotoParameters` | An array of settings passed to page.goto(url, parameters) function. |

### Global Scenario Properties

One may opt to include any of the above properties at the "global" level, in the `scenarioDefaults` configuration object.

<details>
<summary>Expand Example</summary>

```json
{
"id": "backstop_playwright",
"viewports": [
{
"label": "phone",
"width": 320,
"height": 480
},
{
"label": "tablet",
"width": 1024,
"height": 768
}
],
"onBeforeScript": "playwright/onBefore.js",
"onReadyScript": "playwright/onReady.js",
"scenarioDefaults": {
"cookiePath": "backstop_data/engine_scripts/cookies.json",
"url": "https://garris.github.io/BackstopJS/",
"readySelector": "",
"delay": 0,
"hideSelectors": [".getItBlock"],
"removeSelectors": [".logoBlock"],
"hoverSelector": "",
"clickSelector": "",
"postInteractionWait": 1000,
"selectors": [],
"selectorExpansion": true,
"misMatchThreshold" : 0.1,
"requireSameDimensions": true
},
"scenarios": [
{
"label": "BackstopJS Homepage",
"cookiePath": "backstop_data/engine_scripts/cookies.json",
"url": "https://garris.github.io/BackstopJS/",
"referenceUrl": "",
"readyEvent": "",
"readySelector": "",
"delay": 0,
"hoverSelector": "",
"clickSelector": "",
"selectors": [],
"selectorExpansion": true,
"misMatchThreshold" : 0.1,
"requireSameDimensions": true
}
],
"paths": {
"bitmaps_reference": "backstop_data/bitmaps_reference",
"bitmaps_test": "backstop_data/bitmaps_test",
"engine_scripts": "backstop_data/engine_scripts",
"html_report": "backstop_data/html_report",
"ci_report": "backstop_data/ci_report"
},
"report": ["browser"],
"engine": "playwright",
"engineOptions": {
"args": ["--no-sandbox"]
},
"asyncCaptureLimit": 5,
"asyncCompareLimit": 50,
"debug": false,
"debugWindow": false,
"archiveReport": true,
"scenarioLogsInReports": true
}
```

</details>

> [!IMPORTANT]
> Global configuration is overridden at the `scenario` level. A scenario with `selectors: []` set as an empty array will yield zero selectors. E.g. `scenarioDefaults.selectors: [".fancy", ".global", ".classes"]` will be set to `[]`, as `scenario.selectors` takes precedence.
### Advanced Scenarios

#### Testing Click and Hover Interactions
Expand Down
26 changes: 16 additions & 10 deletions core/util/engineTools.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
/**
* @description Retrieves the mismatch threshold based on the given scenario and configuration.
*
* @param {Object} scenario - The scenario object, which may contain a misMatchThresholdconfig property.
* @param {Object} config - The configuration object, which includes misMatchThreshold and defaultMisMatchThreshold properties.
* @returns {number} The mismatch threshold value.
*/
function getMisMatchThreshHold (scenario, config) {
if (typeof scenario.misMatchThreshold !== 'undefined') { return scenario.misMatchThreshold; }
if (typeof config.misMatchThreshold !== 'undefined') { return config.misMatchThreshold; }
return config.defaultMisMatchThreshold;
return scenario?.misMatchThresholdconfig || config?.misMatchThreshold || config?.defaultMisMatchThreshold || 0.1;
}

function ensureFileSuffix (filename, suffix) {
Expand Down Expand Up @@ -30,14 +35,15 @@ function genHash (str) {
return hash.toString().replace(/^-/, 0);
}

/**
* @description Determines whether the same dimensions are required based on the given scenario and configuration.
*
* @param {Object} scenario - The scenario object, which may contain a requireSameDimensions property.
* @param {Object} config - The configuration object, which includes requireSameDimensions and defaultMisMatchThreshold properties.
* @returns {boolean} True if the same dimensions are required, otherwise false.
*/
function getRequireSameDimensions (scenario, config) {
if (scenario.requireSameDimensions !== undefined) {
return scenario.requireSameDimensions;
} else if (config.requireSameDimensions !== undefined) {
return config.requireSameDimensions;
} else {
return config.defaultRequireSameDimensions;
}
return scenario?.requireSameDimensions || config?.requireSameDimensions || config?.defaultMisMatchThreshold || true;
}

function getSelectorName (selector) {
Expand Down
20 changes: 13 additions & 7 deletions core/util/runPlaywright.js
Original file line number Diff line number Diff line change
Expand Up @@ -104,11 +104,7 @@ module.exports.createPlaywrightBrowser = async function (config) {
return await playwright[browserChoice].launch(playwrightArgs);
};

module.exports.runPlaywright = function (args) {
const scenario = args.scenario;
const viewport = args.viewport;
const config = args.config;
const browser = args._playwrightBrowser;
module.exports.runPlaywright = function ({ scenario, viewport, config, _playwrightBrowser: browser }) {
const scenarioLabelSafe = engineTools.makeSafe(scenario.label);
const variantOrScenarioLabelSafe = scenario._parent ? engineTools.makeSafe(scenario._parent.label) : scenarioLabelSafe;

Expand All @@ -127,7 +123,18 @@ module.exports.disposePlaywrightBrowser = async function (browser) {
};

async function processScenarioView (scenario, variantOrScenarioLabelSafe, scenarioLabelSafe, viewport, config, browser) {
const { engineOptions } = config;
const { engineOptions, scenarioDefaults = {} } = config;

/**
* @type {Object}
* @description Spread `scenarioDefaults` into the scenario.
* @default `scenario`
*/
scenario = {
...scenarioDefaults,
...scenario
};

if (!config.paths) {
config.paths = {};
}
Expand Down Expand Up @@ -220,7 +227,6 @@ async function processScenarioView (scenario, variantOrScenarioLabelSafe, scenar
timeout: readyTimeout
});
}
//

// --- DELAY ---
if (scenario.delay > 0) {
Expand Down
17 changes: 13 additions & 4 deletions core/util/runPuppet.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,7 @@ const DOCUMENT_SELECTOR = 'document';
const NOCLIP_SELECTOR = 'body:noclip';
const VIEWPORT_SELECTOR = 'viewport';

module.exports = function (args) {
const scenario = args.scenario;
const viewport = args.viewport;
const config = args.config;
module.exports = function ({ scenario, viewport, config }) {
const scenarioLabelSafe = engineTools.makeSafe(scenario.label);
const variantOrScenarioLabelSafe = scenario._parent ? engineTools.makeSafe(scenario._parent.label) : scenarioLabelSafe;

Expand Down Expand Up @@ -53,6 +50,18 @@ function loggerAction (action, color, message, ...rest) {
}

async function processScenarioView (scenario, variantOrScenarioLabelSafe, scenarioLabelSafe, viewport, config, logger) {
const { scenarioDefaults = {} } = config;

/**
* @type {Object}
* @description Spread `scenarioDefaults` into the scenario.
* @default `scenario`
*/
scenario = {
...scenarioDefaults,
...scenario
};

if (!config.paths) {
config.paths = {};
}
Expand Down

0 comments on commit 0c8ead0

Please sign in to comment.