Skip to content

Providing a way to take screenshots of the TYPO3 CMS in a scripted way.

License

Notifications You must be signed in to change notification settings

TYPO3-Documentation/t3docs-screenshots

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Testing Status 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:

Activity diagram of the screenshots runner

Install

  1. Docker
  2. Docker-Compose
  3. DDEV
  1. Install the project by

    ddev install
  2. Test the project by

    1. creating a dummy screenshots.json with example entries at public/t3docs/My-Manual by

      ddev init-screenshot-json -t My-Manual
    2. running the dummy screenshots.json by

      ddev make-screenshots -t My-Manual
    3. 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

ddev start

Stop the project by

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

ddev install

or by resetting a single suite TYPO3 instance with

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

ddev install --initialize-suites-only

or by reflecting to a single suite TYPO3 instance with

ddev install --initialize-suites-only -s [suite-id]

Remove the project by

ddev delete -yO
  1. Start the project - if not already present.
  2. Navigate the browser to one or more of these URLs:
  3. 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.

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

ddev auth ssh
ddev fetch-manuals

or limit it to either the official TYPO3 Documentation manuals with

ddev auth ssh
ddev fetch-manuals -c documentation

or the officially supported TYPO3 projects with

ddev auth ssh
ddev fetch-manuals -c application

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

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:

{
   "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.

{
    "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.

{
   "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.

{
   "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.

{
   "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.

{
   "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.

{
   "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.

{
   "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.

{
   "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.

{
   "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:

{
   "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.

{
   "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

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

  1. determine the most suitable distribution for creating the custom element:

    • EXT:examples

      This distribution is owned by the TYPO3 Documentation Team and is the fallback if no other distribution is more suitable.

    • EXT: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

      This distribution is mainly used in the TYPO3 Core test environment. It generates a lot of content elements for acceptance tests.

  2. create a new Git branch in that distribution folder (see subfolders of public/typo3conf/ext/)

  3. log into the suite TYPO3 instance which uses that distribution (see URLs in section "Browsable TYPO3 Instances")

  4. create the new content element

  5. export the page tree (see section "Database Data" of the distribution tutorial)

  6. overwrite the existing data.xml file and data.xml.files folder of the distribution folder by the export

  7. 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.

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.

ddev make-screenshots -t TYPO3CMS-Reference-TCA
ddev make-screenshots -s Install
ddev make-screenshots -s Core
ddev make-screenshots -s Examples
ddev make-screenshots -s ExtensionBuilder
ddev make-screenshots -s Introduction
ddev make-screenshots -s SitePackage
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.

{
   "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"},
            ]
         }
      }
   }
}
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") 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:

  • create screenshots by processing the available screenshots.json through the screenshots runner or
  • compare new screenshots with the originals and copy the new screenshots

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.

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.

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.

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.

docs/screenshots_manager_copy.png

Eventually, the original screenshots were updated and the changes can be committed and pushed.

Run unit tests by

ddev run-unit-tests

Run unit tests with code coverage by

ddev xdebug on
ddev run-unit-tests -c
ddev xdebug off