|BadgeTestingStatus| |BadgeCodeCoverage|
.. |BadgeTestingStatus| image:: https://github.com/TYPO3-Documentation/t3docs-screenshots/actions/workflows/tests.yml/badge.svg :alt: Testing Status
.. |BadgeCodeCoverage| image:: https://byob.yarr.is/TYPO3-Documentation/t3docs-screenshots/code-coverage :alt: Code Coverage
This project provides a way to take screenshots of the TYPO3 CMS in a scripted way.
First, the user browses TYPO3 instances to take notes of a click path for a new screenshot.
Next, the click path gets forged to a screenshots.json
file.
Then, all screenshots.json
files get executed by the screenshots runner which produces the screenshots.
Last, the user compares the actual screenshots to the original screenshots in the screenshots manager and copies over if
approved.
In order to provide a wide range of screenshots, this project comes with a set of pre-configured TYPO3 environments with
initialized page trees, so-called suites. Each TYPO3 instance of a suite can be accessed at a specific URL and
configured for use by the screenshot runner in the `screenshots.json
file.
Activity of the screenshots runner:
.. image:: docs/screenshots_runner_diagram.png :alt: Activity diagram of the screenshots runner
.. contents:: Table of Contents
Install
Docker <https://docs.docker.com/get-docker/>
_Docker-Compose <https://docs.docker.com/compose/install/>
_DDEV <https://ddev.readthedocs.io/en/stable/>
_.. _installation:
Install the project by
.. code-block:: bash
ddev install
Test the project by
a. creating a dummy screenshots.json
with example entries at public/t3docs/My-Manual
by
.. code-block:: bash
ddev init-screenshot-json -t My-Manual
b. running the dummy screenshots.json
by
.. code-block:: bash
ddev make-screenshots -t My-Manual
c. approving your installation by confirming that the screenshots have been created in
public/t3docs-generated/actual/My-Manual
.
Now you are ready to browse the suite TYPO3 instances, create custom screenshots.json
files and generate screenshots
from them.
Below is a list of common commands for handling the project.
Start the project by
.. code-block:: bash
ddev start
Stop the project by
.. code-block:: bash
ddev stop
You might want to setup the project or a single suite TYPO3 instance from scratch to remove all temporary changes of it. This can be reliably achieved by resetting the project with
.. code-block:: bash
ddev install
or by resetting a single suite TYPO3 instance with
.. code-block:: bash
ddev install -s [suite-id]
again. Available suite IDs are "core", "examples", "extension-builder", "install", "introduction", "site-package" and "styleguide".
Instead of re-installing the project or suite TYPO3 instance and lose all database changes, you might want to only reflect updates of the project composer packages in your suites TYPO3 instances packages. Do this with
.. code-block:: bash
ddev install --initialize-suites-only
or by reflecting to a single suite TYPO3 instance with
.. code-block:: bash
ddev install --initialize-suites-only -s [suite-id]
Remove the project by
.. code-block:: bash
ddev delete -yO
.. _browsable-typo3-instances:
Start the project - if not already present.
Navigate the browser to one or more of these URLs:
Log in to the TYPO3 backend with credentials "admin" and "password".
Now you are ready to browse the suite TYPO3 backends and look up element selectors for use in actions of your
screenshots.json
.
The runner scans the sub folders of public/t3docs
, processes the public/t3docs/*/screenshots.json
files and
creates the screenshots in public/t3docs-generated/actual/*/
where they get further processed by the screenshots
manager. Please note that public/t3docs-generated/actual/*/
is cleaned up before the run, so it does not contain
outdated screenshots.
public/t3docs
The folders in public/t3docs
should contain the official TYPO3 Documentation manuals or other documentation that
needs fresh screenshots of TYPO3. Get all official TYPO3 Documentation manuals and other officially supported TYPO3
projects in one bundle (requires access permission) by
.. code-block:: bash
ddev auth ssh ddev fetch-manuals
or limit it to either the official TYPO3 Documentation manuals with
.. code-block:: bash
ddev auth ssh ddev fetch-manuals -c documentation
or the officially supported TYPO3 projects with
.. code-block:: bash
ddev auth ssh ddev fetch-manuals -c application
screenshots.json
The runner configuration file screenshots.json
must be placed in the root directory of the respective documentation
folder, i.e. in public/t3docs/*/screenshots.json
. It defines in the first level the suite
("Core", "Examples", "ExtensionBuilder", "Install", "Introduction", "SitePackage" or "Styleguide")
where the screenshots are taken,
and in the second level it lists blocks of browser actions. Each action is an object, where the key action
marks
the action name and the remaining keys represent the action parameters.
Actions are mainly about navigating the suite TYPO3 instance and taking screenshots.
Create a basic screenshots.json
in an arbitrary manual folder at public/t3docs
by
.. code-block:: bash
ddev init-screenshot-json [-t folder]
where folder
defaults to My-Manual
if left blank.
This is a small runner configuration which takes screenshots of all available suites:
.. code-block:: json
{ "suites": { "Core": { "screenshots": [ [ {"action": "makeScreenshotOfWindow", "fileName": "CoreDashboard"} ] ] }, "Examples": { "screenshots": [ [ {"action": "makeScreenshotOfFullPage", "fileName": "ExamplesDashboardFullPage"} ] ] }, "ExtensionBuilder": { "screenshots": [ [ {"action": "see", "text": "Extension Builder"}, {"action": "click", "link": "Extension Builder"}, {"action": "makeScreenshotOfFullPage", "fileName": "ExtensionBuilderFullPage"} ] ] }, "Install": { "screenshots": [ [ {"action": "makeScreenshotOfFullPage", "fileName": "InstallationFullPage"} ] ] }, "Introduction": { "screenshots": [ [ {"action": "makeScreenshotOfFullPage", "fileName": "IntroductionDashboardFullPage"} ] ] }, "SitePackage": { "screenshots": [ [ {"action": "makeScreenshotOfFullPage", "fileName": "SitePackageDashboardFullPage"} ] ] }, "Styleguide": { "screenshots": [ [ {"action": "makeScreenshotOfRecord", "table": "pages", "uid": 1, "fileName": "StyleguideFirstPageRecord"} ], [ {"action": "makeScreenshotOfField", "table": "pages", "uid": 1, "fields": "abstract", "fileName": "StyleguideFirstPageRecordWithAbstractFieldOnly"}, ] ] } } }
Screenshots are mainly made by the actions makeScreenshotOfWindow
, makeScreenshotOfFullPage
,
makeScreenshotOfContentFrame
and makeScreenshotOfElement
, the first one taking a screenshot of the browser
window, the second one taking a screenshot of the whole TYPO3 page, the third one only of the TYPO3 backend content
frame and the last one of a specific DOM element, e.g.
.. code-block:: json
{ "suites": { "Core": { "screenshots": [ [ {"action": "see", "text": "List"}, {"action": "click", "link": "List"}, {"action": "waitForText", "text": "New TYPO3 site"}, {"action": "makeScreenshotOfWindow", "fileName": "Typo3Window"}, {"action": "makeScreenshotOfFullPage", "fileName": "Typo3FullPage"}, {"action": "makeScreenshotOfContentFrame", "fileName": "Typo3ContentFrameOnly"}, {"action": "makeScreenshotOfElement", "selector": ".topbar-header-site", "fileName": "Typo3ElementOnly"} ] ] } } }
The captured screenshot might contain too much information that is not needed for the documentation. Therefore it can
be cropped for the purpose of the documentation - or the width of the documentation page - with cropScreenshot
,
e.g.
.. code-block:: json
{ "suites": { "Introduction": { "screenshots": [ [ {"action": "makeScreenshotOfFullPage", "fileName": "IntroductionCropRightTop"}, {"action": "cropScreenshot", "fileName": "IntroductionCropRightTop", "position": "right-top", "height": 400, "width": 400}, ] ] } } }
The target folder of the screenshots is Images/AutomaticScreenshots
by default and is calculated
relative to the screenshots.json
. The path can be adapted by the actions setScreenshotsDocumentationPath
and
setScreenshotsImagePath
respectively, e.g.
.. code-block:: json
{ "suites": { "Introduction": { "screenshots": [ [ {"action": "setScreenshotsDocumentationPath", "path": "IntroductionDocumentation"}, {"action": "setScreenshotsImagePath", "path": "Images/IntroductionScreenshots"}, {"action": "makeScreenshotOfWindow", "fileName": "IntroductionDashboard"} ] ] } } }
which would result in a target folder IntroductionDocumentation/Images/IntroductionScreenshots
.
To steer the runner through the TYPO3 backend, many TYPO3 specific actions have been added to the general browser navigation actions, e.g.
.. code-block:: json
{ "suites": { "Styleguide": { "screenshots": [ [ {"action": "switchToMainFrame"}, {"action": "scrollModuleMenuTo", "toSelector": "#web_list"}, {"action": "click", "link": "List"}, {"action": "openPageTreePath", "path": ["styleguide TCA demo", "elements rte"]}, {"action": "scrollPageTreeTo", "toSelector": "#identifier-0_12"}, {"action": "switchToContentFrame"}, {"action": "waitForText", "text": "elements rte", "timeout": 5}, {"action": "scrollModuleBodyToBottom"}, {"action": "makeScreenshotOfWindow", "fileName": "StylesheetContentScrolledDown"}, ] ] } } }
To guide the reader of the documentation over the screenshot, DOM elements can be highlighted by actions drawBox
,
drawArrow
, drawBadge
, etc. and the highlighting can be removed later by action clearDrawings
, e.g.
.. code-block:: json
{ "suites": { "Introduction": { "screenshots": [ [ {"action": "drawBox", "selector": "#dashboard"}, {"action": "drawArrow", "selector": "#dashboard", "position": "right-bottom"}, {"action": "drawBadge", "selector": "#dashboard", "label": "Click here", "position": "bottom"}, {"action": "makeScreenshotOfWindow", "fileName": "IntroductionDashboardWithHighlightedMenuitem"}, {"action": "clearDrawings"}, {"action": "makeScreenshotOfWindow", "fileName": "IntroductionDashboardWithoutHighlightedMenuitem"} ] ] } } }
Along with the screenshot a reStructuredText file gets created automatically in the folder Images/Rst
and can be used to include the screenshot comfortably into a documentation. The path can be changed by the actions
setScreenshotsDocumentationPath
and setScreenshotsRstPath
and the automatic creation can be switched via action
createScreenshotsRstFile
, e.g.
.. code-block:: json
{ "suites": { "Introduction": { "screenshots": [ [ {"action": "setScreenshotsDocumentationPath", "path": "IntroductionDocumentation"}, {"action": "setScreenshotsRstPath", "path": "Images/IntroductionRst"}, {"action": "makeScreenshotOfWindow", "fileName": "IntroductionDashboardWithRstFile"}, {"action": "createScreenshotsRstFile", "create": false}, {"action": "makeScreenshotOfWindow", "fileName": "IntroductionDashboardWithoutRstFile"} ] ] } } }
which would result in a target folder IntroductionDocumentation/Images/IntroductionRst
for reStructuredText files.
Another redundant documentation job besides taking screenshots is to insert and update code snippets. With action
createCodeSnippet
a specific TYPO3 code source file gets transformed into a reStructuredText file for inclusion and
gets saved to folder CodeSnippets
. The folder can be changed by setScreenshotsDocumentationPath
and
setCodeSnippetsTargetPath
.
Furthermore there are dedicated actions like createJsonCodeSnippet
, createPhpArrayCodeSnippet
,
createPhpClassCodeSnippet
, createXmlCodeSnippet
or createYamlCodeSnippet
to store only excerpts of code
files, e.g.
.. code-block:: json
{ "suites": { "Styleguide": { "screenshots": [ [ {"action": "setScreenshotsDocumentationPath", "path": "StyleguideDocumentation"}, {"action": "setCodeSnippetsTargetPath", "path": "CodeSnippets/StyleguideCode"}, {"action": "createCodeSnippet", "sourceFile": "typo3/sysext/core/Configuration/TCA/be_groups.php", "targetFileName": "CoreBeGroups"}, { "action": "createCodeSnippet", "sourceFile": "typo3/sysext/core/Configuration/TCA/be_groups.php", "targetFileName": "CoreBeGroupsWithHighlights", "caption": "I am the caption", "name": "i-am-the-target-name", "showLineNumbers": true, "lineStartNumber": 1, "emphasizeLines": [5,6,7] } {"action": "createJsonCodeSnippet", "sourceFile": "typo3/sysext/core/composer.json", "fields": ["name", "support/source"], "targetFileName": "CoreComposerJsonDescription"}, {"action": "createPhpArrayCodeSnippet", "sourceFile": "typo3/sysext/core/Configuration/TCA/be_groups.php", "fields": ["types"], "targetFileName": "CoreBeGroupsTypes"}, {"action": "createPhpClassCodeSnippet", "class": "TYPO3\CMS\Core\Cache\Backend\FileBackend", "members": ["frozen", "freeze"], "withComment": true, "targetFileName": "FileBackendFreezeWithComments"}, {"action": "createXmlCodeSnippet", "sourceFile": "typo3/sysext/form/Configuration/FlexForms/FormFramework.xml", "nodes": ["T3DataStructure/sheets/sDEF"], "targetFileName": "FormFrameworkXmlSheetSDef"}, {"action": "createYamlCodeSnippet", "sourceFile": "typo3/sysext/core/Configuration/Services.yaml", "fields": ["services/_defaults"], "targetFileName": "CoreServicesYamlDefaults"} ] ] } } }
which would result in a target folder StyleguideDocumentation/CodeSnippets/StyleguideCode
for code snippets.
Actions can be nested to use the return value of the inner action by the outer, e.g.
.. code-block:: json
{ "suites": { "Styleguide": { "screenshots": [ [ { "action": "makeScreenshotOfRecord", "uid": {"action": "getUidByField", "table": "pages", "field": "title", "value": "elements group"}, "table": "pages", "fileName": "StyleguidePageRecordWithSpecificTitle" } ] ] } } }
which executes the action getUidByField
and uses the return value for parameter uid
of action
makeScreenshotOfRecord
.
Comments can be inserted to facilitate maintenance work, e.g.
.. code-block:: json
{ "suites": { "Styleguide": { "screenshots": [ [ {"comment": "****"}, {"comment": "Take screenshot of TYPO3 TCA record."}, {"comment": "****"}, {"action": "makeScreenshotOfRecord", "table": "pages", "uid": 3, "fileName": "StyleguidePageRecordWithUid3"}, ] ] } } }
Files can be created and deleted in the public path of TYPO3 by actions writeFileToTypo3PublicPath
and
deleteFileInTypo3PublicPath
, e.g. to bypass access restrictions of the TYPO3 installation process:
.. code-block:: json
{ "suites": { "Install": { "screenshots": [ [ {"action": "deleteFileInTypo3PublicPath", "filePath": "FIRST_INSTALL"}, {"action": "reloadInstallationProcess"}, {"action": "makeScreenshotOfElement", "selector": ".typo3-install-content", "fileName": "InstallationStep0"}, {"action": "writeFileToTypo3PublicPath", "filePath": "FIRST_INSTALL"}, {"action": "reloadInstallationProcess"}, {"action": "makeScreenshotOfElement", "selector": ".typo3-install-content", "fileName": "InstallationStep1"} ] ] } } }
An action block can be included in another action block of the same suite by assigning a custom identifier to the former
and using that identifier in the latter with the include
directive, e.g.
.. code-block:: json
{ "suites": { "Styleguide": { "screenshots": { "_default": [ {"action": "resizeWindow", "width": 1024, "height": 768} ], "list": [ {"include": "_default"}, {"action": "see", "text": "List"}, ] } } } }
where the actions with ID "_default" are included and executed at the beginning of the action block with ID "list".
Action blocks will not be executed directly if their custom identifier starts with an underscore. Therefore it is useful to use such underscore identifiers for action blocks that are intended for inclusion only.
Included blocks can themselves include other blocks.
As action all codeception actions are supported including the actions of the packages typo3/testing-framework
and
t3docs/screenshots
. All available actions get compiled into
packages/screenshots/Classes/Runner/Codeception/Support/_generated/PhotographerActions.php
- ready for lookup.
A new action should be added to the files of packages/screenshots/Classes/Runner/Codeception/Support/Helper
and then be
compiled into the PhotographerActions.php
by
.. code-block:: bash
ddev exec vendor/bin/codecept build -c public/typo3conf/ext/screenshots/Classes/Runner/codeception.yml
In this project, TYPO3 distributions are used to provide a variety of content elements that can be browsed via actions and from which screenshots can be taken. If the documentation author misses a custom content element, even after rechecking all included distributions, the author has to
determine the most suitable distribution for creating the custom element:
EXT:examples <https://github.com/TYPO3-Documentation/t3docs-examples>
_
This distribution is owned by the TYPO3 Documentation Team and is the fallback if no other distribution is more suitable.
EXT:introduction <https://github.com/TYPO3-Documentation/introduction>
_
This distribution is aimed at the TYPO3 community and serves in general as a showcase for TYPO3 and in particular
as a showcase for the underlying EXT:bootstrap_package
which integrates the Twitter Bootstrap content elements
into TYPO3.
EXT:styleguide <https://github.com/TYPO3-Documentation/styleguide>
_
This distribution is mainly used in the TYPO3 Core test environment. It generates a lot of content elements for acceptance tests.
create a new Git branch in that distribution folder (see subfolders of public/typo3conf/ext/
)
log into the suite TYPO3 instance which uses that distribution (see URLs in section "Browsable TYPO3 Instances <browsable-typo3-instances_>
_")
create the new content element
export the page tree (see section
"Database Data <https://docs.typo3.org/m/typo3/reference-coreapi/master/en-us/ExtensionArchitecture/CreateNewDistribution/#database-data>
_"
of the distribution tutorial)
overwrite the existing data.xml
file and data.xml.files
folder of the distribution folder by the export
commit and push the changes of the distribution folder, create a pull request from it and wait for merging by the TYPO3 Documentation Team.
Once the changes are merged, actions can be added to create the corresponding screenshot.
.. code-block:: bash
ddev make-screenshots
A folder path can be specified to process only the screenshots.json
of this particular folder and its subfolders.
The folder path can be defined as an absolute path or relative to public/t3docs
, e.g. this command executes
public/t3docs/TYPO3CMS-Reference-TCA/Documentation/screenshots.json
.
.. code-block:: bash
ddev make-screenshots -t TYPO3CMS-Reference-TCA
.. code-block:: bash
ddev make-screenshots -s Install
.. code-block:: bash
ddev make-screenshots -s Core
.. code-block:: bash
ddev make-screenshots -s Examples
.. code-block:: bash
ddev make-screenshots -s ExtensionBuilder
.. code-block:: bash
ddev make-screenshots -s Introduction
.. code-block:: bash
ddev make-screenshots -s SitePackage
.. code-block:: bash
ddev make-screenshots -s Styleguide
A custom identifier can be assigned to an action block and then used to execute only that specific subset of actions. However, action blocks cannot be executed if their custom identifier begins with an underscore, which is intended for inclusion in other action blocks.
.. code-block:: json
{ "suites": { "Styleguide": { "screenshots": { "first-page": [ {"action": "makeScreenshotOfRecord", "table": "pages", "uid": 1, "fileName": "StyleguideFirstPageRecord"} ], "first-page-with-specific-field": [ {"action": "makeScreenshotOfField", "table": "pages", "uid": 1, "fields": "abstract", "fileName": "StyleguideFirstPageRecordWithAbstractFieldOnly"}, ] } } } }
.. code-block:: bash
ddev make-screenshots -s Styleguide -a first-page
To manage the created screenshots, the TYPO3 instance backend of the screenshots manager
(see URL in section "Browsable TYPO3 Instances <browsable-typo3-instances_>
_") provides a module "Screenshots", which
can be found in the module menu under Admin Tools > Screenshots. It provides three functions: Starting the screenshot
runner, comparing actual and original screenshots and copying screenshots from the actual path to the original path.
On the welcome page you can select the action you want to perform:
screenshots.json
through the screenshots runner or.. image:: docs/screenshots_manager_welcome.png
On this page you automatically start the screenshots runner, which starts a subprocess on the command line. The result is displayed on this page as soon as the runner is finished - which may take a while.
.. image:: docs/screenshots_manager_make.png
To comfortably work with a large number of screenhots.json
and actions, the number of actions can be reduced by
using the filter at the top of the page: Only actions matching the path, suite ID and actions ID criteria will then be
executed.
On this page you compare the newly created screenshots of the runner with the originals. Each list item shows the current state on the left, the original state on the right and the difference map in the middle. At the top it shows the difference as a number.
Each screenshot is selected for copying by default, but can be deselected individually and in the aggregation. The same applies to text files such as the screenshot reST include files or the code snippets.
.. image:: docs/screenshots_manager_compare.png
To work comfortably with a large number of files, the list of screenshots and text files can be reduced by entering a path in the search field at the top of the page: Only files with a matching path will then be displayed. Regular expressions are supported and automatic suggestion of available paths is enabled.
.. image:: docs/screenshots_manager_compare_searchbox.png
Optionally sort the list by criteria, such as difference, file name or file path.
When you have confirmed the changes, pressing the "Copy screenshots" button will copy the screenshots to the original location.
.. image:: docs/screenshots_manager_copy.png
Eventually, the original screenshots were updated and the changes can be committed and pushed.
Run unit tests by
.. code-block:: bash
ddev run-unit-tests
Run unit tests with code coverage by
.. code-block:: bash
ddev xdebug on ddev run-unit-tests -c ddev xdebug off