-
Notifications
You must be signed in to change notification settings - Fork 13
OEL-4248: VRT Backstop #535
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: 1.x
Are you sure you want to change the base?
Changes from all commits
f6d0bf4
d389bc8
f4aee46
1e07320
f0b6ef2
fcbd78b
645e0e7
5f8e190
e878b8d
0f87288
1e73893
01a66e6
8e5abfe
245f040
d10555b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,60 @@ | ||
| # Drupal git normalization | ||
| # @see https://www.kernel.org/pub/software/scm/git/docs/gitattributes.html | ||
| # @see https://www.drupal.org/node/1542048 | ||
| # Normally these settings would be done with macro attributes for improved | ||
| # readability and easier maintenance. However macros can only be defined at the | ||
| # repository root directory. Drupal avoids making any assumptions about where it | ||
| # is installed. | ||
| # Define text file attributes. | ||
| # - Treat them as text. | ||
| # - Ensure no CRLF line-endings, neither on checkout nor on checkin. | ||
| # - Detect whitespace errors. | ||
| # - Exposed by default in `git diff --color` on the CLI. | ||
| # - Validate with `git diff --check`. | ||
| # - Deny applying with `git apply --whitespace=error-all`. | ||
| # - Fix automatically with `git apply --whitespace=fix`. | ||
| *.config text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 | ||
| *.css text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 | ||
| *.dist text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 | ||
| *.engine text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=php linguist-language=php | ||
| *.html text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=html | ||
| *.inc text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=php linguist-language=php | ||
| *.install text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=php linguist-language=php | ||
| *.js text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 | ||
| *.json text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 | ||
| *.lock text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 | ||
| *.map text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 | ||
| *.md text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 | ||
| *.module text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=php linguist-language=php | ||
| *.php text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=php linguist-language=php | ||
| *.po text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 | ||
| *.profile text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=php linguist-language=php | ||
| *.script text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 | ||
| *.sh text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=php linguist-language=php | ||
| *.sql text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 | ||
| *.svg text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 | ||
| *.theme text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=php linguist-language=php | ||
| *.twig text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 | ||
| *.txt text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 | ||
| *.xml text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 | ||
| *.yml text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 | ||
| # PHPStan's baseline uses tabs instead of spaces. | ||
| core/.phpstan-baseline.php text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tabwidth=2 diff=php linguist-language=php | ||
| # Define binary file attributes. | ||
| # - Do not treat them as text. | ||
| # - Include binary diff in patches instead of "binary files differ." | ||
| *.avif -text diff | ||
| *.eot -text diff | ||
| *.exe -text diff | ||
| *.gif -text diff | ||
| *.gz -text diff | ||
| *.ico -text diff | ||
| *.jpeg -text diff | ||
| *.jpg -text diff | ||
| *.otf -text diff | ||
| *.phar -text diff | ||
| *.png filter=lfs diff=lfs merge=lfs -text | ||
| *.svgz -text diff | ||
| *.ttf -text diff | ||
| *.woff -text diff | ||
| *.woff2 -text diff | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We might want to check with QA if we can run this in gitlab.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's only start this conversation once we are happy with what we have. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,71 @@ | ||
| name: BackstopJS VRT | ||
|
|
||
| on: | ||
| pull_request: | ||
|
|
||
| jobs: | ||
| backstop: | ||
| runs-on: ubuntu-latest | ||
|
|
||
| steps: | ||
| - name: Checkout | ||
| uses: actions/checkout@v4 | ||
| with: | ||
| lfs: true | ||
|
|
||
| - name: Setup Node | ||
| uses: actions/setup-node@v6 | ||
|
|
||
| - name: Install dependencies | ||
| run: | | ||
| npm install | ||
| npx playwright install --with-deps | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I notice that in Nothing wrong, just an observation :)
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We might want to split this step into two steps, simply to make it easier to see the output from each step in isolation. |
||
|
|
||
| - name: Start Drupal stack | ||
| run: docker compose up -d mysql web | ||
|
|
||
| - name: Install Drupal | ||
| run: | | ||
| docker compose exec -T web composer install | ||
| docker compose exec -T web ./vendor/bin/run drupal:site-install | ||
|
|
||
| - name: Build Backstop config | ||
| run: npm run vrt:build | ||
|
|
||
| - name: Run BackstopJS | ||
| id: backstop | ||
| run: | | ||
| npm run vrt:test | ||
| # Keep artifact uploads running even when Backstop finds visual diffs. | ||
| continue-on-error: true | ||
|
|
||
| - name: Check Backstop report exists | ||
| if: always() | ||
| run: | | ||
| if [ ! -f tests/vrt/html_report/index.html ]; then | ||
| echo "Backstop HTML report was not generated" | ||
| exit 1 | ||
| fi | ||
|
|
||
| - name: Upload Backstop results | ||
| id: upload_report | ||
| if: always() | ||
| uses: actions/upload-artifact@v4 | ||
| with: | ||
| # Preserve the HTML report together with test and reference screenshots. | ||
| name: backstop-results-${{ github.sha }} | ||
| path: | | ||
| tests/vrt/html_report | ||
| tests/vrt/bitmaps_test | ||
| tests/vrt/bitmaps_reference | ||
| if-no-files-found: warn | ||
|
|
||
| - name: Fail if Backstop failed | ||
| if: always() && steps.backstop.outcome != 'success' | ||
| run: | | ||
| echo "::error title=Run BackstopJS failed::Check the 'Run BackstopJS' step above." | ||
| exit 1 | ||
|
|
||
| - name: Stop Drupal stack | ||
| if: always() | ||
| run: docker compose down | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -120,6 +120,10 @@ regardless of your local host configuration. | |
|
|
||
| - [Docker](https://www.docker.com/get-docker) | ||
| - [Docker Compose](https://docs.docker.com/compose/) | ||
| - [Git LFS](https://docs.github.com/en/repositories/working-with-files/managing-large-files/installing-git-large-file-storage) | ||
|
|
||
|
|
||
| > __Important__: Git LFS is required for development. Builds may fail or assets may be missing if Git LFS is not installed and initialized before cloning the repository. | ||
|
|
||
| #### Override docker settings | ||
|
|
||
|
|
@@ -209,6 +213,23 @@ docker-compose exec web npm run build | |
| docker-compose exec web npm run watch | ||
| ``` | ||
|
|
||
|
donquixote marked this conversation as resolved.
|
||
| ## Visual regression testing (BackstopJS) | ||
|
|
||
| BackstopJS lives under `tests/vrt/`. The scenario builder and Playwright helper scripts in this directory generate `tests/vrt/scenarios/patterns.json` and `tests/vrt/backstop.generated.json`, which Backstop consumes for visual checks. | ||
|
|
||
| ### Prerequisites | ||
|
|
||
| - A running Drupal site reachable at `http://localhost:8080/build`. Override the target with the `VRT_BASE_URL` environment variable if needed. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we should simply point to the regular install steps. |
||
| - Valid credentials. The default `admin` / `admin` values can be overridden with `DRUPAL_USER` and `DRUPAL_PASS`. | ||
| - Playwright: `docker compose exec web npx playwright install-deps` | ||
|
|
||
| ### Available commands | ||
|
|
||
| - `docker compose exec web npm run vrt:build` – scrapes the UI Patterns catalog and generates `tests/vrt/scenarios/patterns.json` plus `tests/vrt/backstop.generated.json`. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. When I run this, it tell me to run |
||
| - `docker compose exec web npm run vrt:reference` – captures fresh reference screenshots into `tests/vrt/bitmaps_reference`. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I get a huge diff when I run this. But the images look the same. |
||
| - `docker compose exec web npm run vrt:test` – compares the current UI against the references, writing results to `tests/vrt/bitmaps_test` and `tests/vrt/html_report`. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I tried this. |
||
| - `docker compose exec web npm run vrt:approve` – promotes the latest passing screenshots to the reference set. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. When reading this, I would like to immediately understand in which category each of these commands fall, and when to run each of them:
So here is what I understand:
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we run these commands targeting a specific snapshot or pattern? |
||
|
|
||
| ## Patch BCL components | ||
|
|
||
| BCL components can be patched by using the [`patch-package`](https://www.npmjs.com/package/patch-package) NPM project. | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| { | ||
| "id": "oe_bootstrap_theme", | ||
| "viewports": [ | ||
| { | ||
| "label": "mobile", | ||
| "width": 375, | ||
| "height": 667 | ||
| }, | ||
| { | ||
| "label": "tablet", | ||
| "width": 768, | ||
| "height": 1024 | ||
| }, | ||
| { | ||
| "label": "desktop", | ||
| "width": 1280, | ||
| "height": 800 | ||
| }, | ||
| { | ||
| "label": "wide", | ||
| "width": 1440, | ||
| "height": 900 | ||
| } | ||
| ], | ||
| "onBeforeScript": "playwright/onBefore.js", | ||
| "onReadyScript": "playwright/onReady.js", | ||
| "paths": { | ||
| "bitmaps_reference": "tests/vrt/bitmaps_reference", | ||
| "bitmaps_test": "tests/vrt/bitmaps_test", | ||
| "engine_scripts": "tests/vrt/engine_scripts", | ||
| "html_report": "tests/vrt/html_report", | ||
| "ci_report": "tests/vrt/ci_report" | ||
| }, | ||
| "report": [ | ||
| "browser" | ||
| ], | ||
| "engine": "playwright", | ||
| "engineOptions": { | ||
| "browser": "chromium" | ||
| }, | ||
| "asyncCaptureLimit": 5, | ||
| "asyncCompareLimit": 50, | ||
| "debug": false, | ||
| "debugWindow": false | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I played a bit with LFS myself.
This is great! Let's go with it.