diff --git a/README.md b/README.md index ae468b5..f31d371 100644 --- a/README.md +++ b/README.md @@ -1,98 +1,17 @@ # BackstopJS Addons A library that extends and improves the default options provided by [BackstopJS](https://github.com/garris/BackstopJS). -## Options and features +### Composer -### Scenario setup -By default, the library applies the following optimisations to the scenarios to avoid common loading issues: - - Avoid lazy CSS loading - - Remove lazy loading and force eager on all images and iframes - - Avoid asynchronous image decoding - - Force Drupal.blazy to load all images - - Pause the Slick slider autoplay - - Wait for fonts to load - - Wait for the page to load completely - - Allow setting the `cookiePath` for the cookies.json globally to apply to all scenarios. If set in the scenario configuration, it will override the global configuration. +``composer require --dev metadrop/backstopjs-addons`` -### Stop animations -Allow stopping the CSS animations on the provided CSS selectors, can be set on each scenario using the `stopAnimationsSelectors` property. +You can override the default destination of the library by adding the following parameter to the extra section +of your project's composer.json file: ```json - "scenarios": [ - { - "label": "Stop animations example", - "stopAnimationsSelectors": ".selector, .selector-2" -``` - -### Disable filters -CSS filters can be disabled on the provided CSS selectors, can be set on each scenario using the `disableFiltersSelectors` property. - -```json - "scenarios": [ - { - "label": "Disable filters example", - "disableFiltersSelectors": ".selector, .selector-2" -``` - -### Log in and navigate to a specific page -Allow users to log in and navigate to a specific page before taking a screenshot. To use this feature you need to set at least the following options - - `loginWrapperSelector` - The selector of the element that wraps the login form. - - `loginUser` - The username to login with - - `loginPass` - The password to login with - -Optionally, `loginRedirectTo` can be set to navigate to a specific page after login. - -```json - "scenarios": [ - { - "label": "Login and navigate to a specific page", - "loginWrapperSelector": ".login-form", - "loginUser": "user", - "loginPass": "pass", - "loginRedirectTo": "/admin" - } -``` - -`loginUser` and `loginPass` can be set globally in the 'backstopjsAddons' settings or in the scenario configuration. If you set the login in the global configuration, you can override it in the scenario configuration. - -```json - "backstopjsAddons": { - "loginUser": "global username", - "loginPass": "global pass" - } -``` - -The `removeSelectors` option is applied after login and navigation. - -### Wait for selector after interaction -This option allows you to wait for a selector to appear after an interaction. This feature is configured within a scenario using the `waitForSelectorAfterInteraction' property, which takes a CSS selector. - -```json - "scenarios": [ - { - "label": "Click an wait for selector example", - "waitForSelectorAfterInteraction": ".selector" -``` - -### Custom user agent by viewport -Allow a user agent to be set on the viewport. - -```json - "viewports": [ - { - "label": "phone", - "width": 375, - "height": 667 - "userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_1 like Mac OS X) AppleWebKit/603.1.30 (KHTML, like Gecko) Version/10.0 Mobile/14E304 Safari/602.1" - }, -``` - -### Hide iframe content -This option replaces the specified iframe(s) with a grey background, maintaining the size of the iframe. This feature is configured within a scenario using the `hideIframeContent' property, which takes a comma-separated list of CSS selectors. - -```json - "scenarios": [ - { - "label": "Hide iframe content example", - "hideIframeContent": ".iframe-container-selector, .iframe-container-selector-2" -``` +"extra": { + "backstop-addons": { + "destinition": "custom/destinition" + } +``` + \ No newline at end of file diff --git a/addons/README.md b/addons/README.md new file mode 100644 index 0000000..ae468b5 --- /dev/null +++ b/addons/README.md @@ -0,0 +1,98 @@ +# BackstopJS Addons +A library that extends and improves the default options provided by [BackstopJS](https://github.com/garris/BackstopJS). + +## Options and features + +### Scenario setup +By default, the library applies the following optimisations to the scenarios to avoid common loading issues: + - Avoid lazy CSS loading + - Remove lazy loading and force eager on all images and iframes + - Avoid asynchronous image decoding + - Force Drupal.blazy to load all images + - Pause the Slick slider autoplay + - Wait for fonts to load + - Wait for the page to load completely + - Allow setting the `cookiePath` for the cookies.json globally to apply to all scenarios. If set in the scenario configuration, it will override the global configuration. + +### Stop animations +Allow stopping the CSS animations on the provided CSS selectors, can be set on each scenario using the `stopAnimationsSelectors` property. + +```json + "scenarios": [ + { + "label": "Stop animations example", + "stopAnimationsSelectors": ".selector, .selector-2" +``` + +### Disable filters +CSS filters can be disabled on the provided CSS selectors, can be set on each scenario using the `disableFiltersSelectors` property. + +```json + "scenarios": [ + { + "label": "Disable filters example", + "disableFiltersSelectors": ".selector, .selector-2" +``` + +### Log in and navigate to a specific page +Allow users to log in and navigate to a specific page before taking a screenshot. To use this feature you need to set at least the following options + - `loginWrapperSelector` - The selector of the element that wraps the login form. + - `loginUser` - The username to login with + - `loginPass` - The password to login with + +Optionally, `loginRedirectTo` can be set to navigate to a specific page after login. + +```json + "scenarios": [ + { + "label": "Login and navigate to a specific page", + "loginWrapperSelector": ".login-form", + "loginUser": "user", + "loginPass": "pass", + "loginRedirectTo": "/admin" + } +``` + +`loginUser` and `loginPass` can be set globally in the 'backstopjsAddons' settings or in the scenario configuration. If you set the login in the global configuration, you can override it in the scenario configuration. + +```json + "backstopjsAddons": { + "loginUser": "global username", + "loginPass": "global pass" + } +``` + +The `removeSelectors` option is applied after login and navigation. + +### Wait for selector after interaction +This option allows you to wait for a selector to appear after an interaction. This feature is configured within a scenario using the `waitForSelectorAfterInteraction' property, which takes a CSS selector. + +```json + "scenarios": [ + { + "label": "Click an wait for selector example", + "waitForSelectorAfterInteraction": ".selector" +``` + +### Custom user agent by viewport +Allow a user agent to be set on the viewport. + +```json + "viewports": [ + { + "label": "phone", + "width": 375, + "height": 667 + "userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_1 like Mac OS X) AppleWebKit/603.1.30 (KHTML, like Gecko) Version/10.0 Mobile/14E304 Safari/602.1" + }, +``` + +### Hide iframe content +This option replaces the specified iframe(s) with a grey background, maintaining the size of the iframe. This feature is configured within a scenario using the `hideIframeContent' property, which takes a comma-separated list of CSS selectors. + +```json + "scenarios": [ + { + "label": "Hide iframe content example", + "hideIframeContent": ".iframe-container-selector, .iframe-container-selector-2" +``` diff --git a/clickAndHoverHelper.js b/addons/clickAndHoverHelper.js similarity index 100% rename from clickAndHoverHelper.js rename to addons/clickAndHoverHelper.js diff --git a/examples/backstop.json b/addons/examples/backstop.json similarity index 100% rename from examples/backstop.json rename to addons/examples/backstop.json diff --git a/examples/bitmaps_reference/.gitignore b/addons/examples/bitmaps_reference/.gitignore similarity index 100% rename from examples/bitmaps_reference/.gitignore rename to addons/examples/bitmaps_reference/.gitignore diff --git a/examples/cookies.json b/addons/examples/cookies.json similarity index 100% rename from examples/cookies.json rename to addons/examples/cookies.json diff --git a/examples/engine_scripts/customScenarioActions.js b/addons/examples/engine_scripts/customScenarioActions.js similarity index 100% rename from examples/engine_scripts/customScenarioActions.js rename to addons/examples/engine_scripts/customScenarioActions.js diff --git a/examples/engine_scripts/onBefore.js b/addons/examples/engine_scripts/onBefore.js similarity index 100% rename from examples/engine_scripts/onBefore.js rename to addons/examples/engine_scripts/onBefore.js diff --git a/examples/engine_scripts/onReady.js b/addons/examples/engine_scripts/onReady.js similarity index 100% rename from examples/engine_scripts/onReady.js rename to addons/examples/engine_scripts/onReady.js diff --git a/loadCookies.js b/addons/loadCookies.js similarity index 100% rename from loadCookies.js rename to addons/loadCookies.js diff --git a/loginAndNavigation.js b/addons/loginAndNavigation.js similarity index 100% rename from loginAndNavigation.js rename to addons/loginAndNavigation.js diff --git a/setup.js b/addons/setup.js similarity index 100% rename from setup.js rename to addons/setup.js diff --git a/userAgentByViewport.js b/addons/userAgentByViewport.js similarity index 100% rename from userAgentByViewport.js rename to addons/userAgentByViewport.js diff --git a/composer.json b/composer.json index 31c443d..c1b3288 100644 --- a/composer.json +++ b/composer.json @@ -1,7 +1,16 @@ { "name": "metadrop/backstopjs-addons", "description": "Metadrop custom backstopjs scripts", - "type": "library", - "minimum-stability": "dev", - "require": {} + "type": "composer-plugin", + "require": { + "composer-plugin-api": "^2.0" + }, + "autoload": { + "psr-4": { + "Metadrop\\BackstopjsAddons\\": "src/" + } + }, + "extra": { + "class": "Metadrop\\BackstopjsAddons\\InstallerPlugin" + } } diff --git a/src/InstallerPlugin.php b/src/InstallerPlugin.php new file mode 100644 index 0000000..fe5ccce --- /dev/null +++ b/src/InstallerPlugin.php @@ -0,0 +1,113 @@ + 'MoveFiles', + ScriptEvents::POST_UPDATE_CMD => 'MoveFiles', + ]; + } + + /** + * Move the BackstopJS Addons files to the tests folder. + * + * @param \Composer\Script\Event $event + * The Composer event. + */ + public function MoveFiles(Event $event) { + $composer = $event->getComposer(); + + // Source + $source = $composer->getConfig()->get('vendor-dir') . '/metadrop/backstopjs-addons/addons'; + + // Destination + $root = $composer->getConfig()->get('vendor-dir') . '/..'; + + $extra = $composer->getPackage()->getExtra(); + $backstop_addons_extras = $extra['backstop-addons'] ?? []; + $destination = $backstop_addons_extras['destination'] ?? 'tests/backstopjs/common/libraries/backstopjs-addons'; + $destination = "{$root}/{$destination}"; + + if (is_dir($destination)) { + self::deleteDirectoryContents($destination); + } else { + mkdir($destination, 0755, TRUE); + } + + self::copyFiles($source, $destination); + } + + /** + * Copy files from source to destination. + * + * @param string $source + * The source folder. + * @param string $destination + * The destination folder. + */ + private function copyFiles($source, $destination) { + $files = scandir($source); + foreach ($files as $file) { + if ($file == '.' || $file == '..') { + continue; + } + if (is_dir($source . '/' . $file)) { + mkdir($destination . '/' . $file); + self::copyFiles($source . '/' . $file, $destination . '/' . $file); + } + else { + copy($source . '/' . $file, $destination . '/' . $file); + } + } + } + + /** + * Delete directory content. + * + * @param string $dir + * The destination folder. + */ + private function deleteDirectoryContents($dir) { + $files = array_diff(scandir($dir), array('.', '..')); + foreach ($files as $file) { + $filePath = $dir . '/' . $file; + if (is_dir($filePath)) { + self::deleteDirectoryContents($filePath); + rmdir($filePath); + } else { + unlink($filePath); + } + } + } + +} \ No newline at end of file