Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
name: tests

on:
push:
pull_request:

jobs:
testsuite:
name: example extension
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1

- name: Install testing system
run: Build/Scripts/runTests.sh -s composerUpdate

- name: Example extension
run: Build/Scripts/runTests.sh -s functional
10 changes: 9 additions & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
```
Documentation/ # the actual manual (reST source, published to docs.typo3.org)
Build/Screenshots/ # takes the generated screenshots, see below
Build/Scripts/runTests.sh # runs the containers that make install and make screenshots need
Build/Scripts/runTests.sh # runs the containers that make install, make screenshots, and make test-extension need
Documentation/CodeSnippets/ # the example extension and site package, whose files the manual includes
Tests/Functional/ # tests of the example extension and site package
CONTRIBUTING.md # how to contribute
```

Expand All @@ -19,6 +21,12 @@ CONTRIBUTING.md # how to contribute
`Build/Screenshots/screenshots.mjs` from a throwaway TYPO3 instance;
`Build/Scripts/runTests.sh -s screenshots Permissions/LimitToLanguages`
takes only the named ones
- `make test-extension` — install the example extension in
`Documentation/CodeSnippets/my_extension/` in a functional test, and
check that its TCA needs no migration and that its labels exist; render
a page with the example site package in
`Documentation/CodeSnippets/my_sitepackage/`, and check its language
menu; CI runs it on every push
- `pre-commit run --all-files` — apply the whitespace hooks
(`trailing-whitespace`, `end-of-file-fixer`) configured in
`.pre-commit-config.yaml`; `pre-commit install` wires them into `git commit`
Expand Down
17 changes: 14 additions & 3 deletions Build/Screenshots/create-records.php
Original file line number Diff line number Diff line change
Expand Up @@ -115,9 +115,8 @@
$arabicPage = $localize('pages', $uids['packingList'], 2);
$process(['pages' => [$arabicPage => ['title' => 'قائمة الأمتعة', 'hidden' => 0]]]);

// A content element of the packing list in Arabic, whose form shows the
// English values below the fields, and which the Records module shows
// below the English one
// A content element of the packing list in Arabic, which the Records
// module shows below the English one
$uids['essentialItems'] = $find('tt_content', 'header', 'Essential Items', $uids['packingList']);
$uids['arabicItems'] = $localize('tt_content', $uids['essentialItems'], 2);
$process(['tt_content' => [$uids['arabicItems'] => ['header' => 'الأغراض الأساسية', 'hidden' => 0]]]);
Expand Down Expand Up @@ -206,6 +205,18 @@
['uid' => $uids['routeComparison']],
);

// A conference of the example extension and its Spanish translation, whose
// form shows the English values below the fields. On the root page, which
// no screenshot of the Records module shows.
$dataHandler = $process(['tx_myextension_conference' => ['NEWconference' => [
'pid' => $uids['root'],
'title' => 'TYPO3 Conference',
'conference_date' => '2026-11-12',
]]]);
$conference = $dataHandler->substNEWwithIDs['NEWconference'];
$uids['spanishConference'] = $localize('tx_myextension_conference', $conference, 1);
$process(['tx_myextension_conference' => [$uids['spanishConference'] => ['title' => 'Conferencia TYPO3']]]);

// A group of translators, who may edit Spanish records only, for the
// screenshot of the language permissions
$dataHandler = $process(['be_groups' => ['NEWtranslators' => [
Expand Down
18 changes: 11 additions & 7 deletions Build/Screenshots/screenshots.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ const margin = 12;
const frontendWidth = 600;

// The uids of the records that create-records.php looked up
const { root, spanishTranslators, packingList, essentialItems, arabicItems, arabicToiletries, privacy, allLanguages, arabicRoutes, faqs, arabicOnly, routeComparison } =
const { root, spanishTranslators, packingList, essentialItems, arabicToiletries, privacy, allLanguages, arabicRoutes, faqs, arabicOnly, routeComparison, spanishConference } =
JSON.parse(readFileSync('../../var/screenshot-records.json', 'utf8'));

// A field of a form, found by its label: the backend runs without debug
Expand Down Expand Up @@ -127,12 +127,16 @@ const screenshots = {
from: '#t3-table-pages_translated',
to: `#t3-table-tt_content tr[data-uid="${essentialItems}"] ~ tr >> nth=1`,
},
// The form of a translation, with the values of the default language
// below the fields. The headlines only, as the text field of an instance
// without the rich text editor shows the HTML.
'CoreSupport/TranslationForm': {
url: editUrl('tt_content', arabicItems),
from: palette('Headlines'),
// The form of a translated record of the example extension, with the
// values of the default language below the fields
'CoreSupport/TranslatingRecord': {
url: editUrl('tx_myextension_conference', spanishConference),
prepare: async (frame) => {
await outline(frame.locator(field('title')));
},
window: true,
// Above the date, whose value below the field counts the days to it
until: '.form-section:has([name$="[title]"])',
},
// A translation whose original changed since it was translated
'CoreSupport/TranslationChanged': {
Expand Down
14 changes: 12 additions & 2 deletions Build/Scripts/runTests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

#
# Runner of the Frontend Localization Guide, based on docker/podman:
# installs the TYPO3 Core that the screenshots are taken from, and takes
# them.
# installs the TYPO3 Core that the screenshots are taken from, takes them,
# and tests the example extension.
#

cleanUp() {
Expand All @@ -25,6 +25,8 @@ Options:
-s <...>
Specifies which suite to run
- composerUpdate: "composer update", handy if host has no PHP
- functional: functional tests of the example extension and the example
site package, on SQLite
- screenshots: screenshots from a TYPO3 instance, optionally only
the ones named as arguments

Expand All @@ -44,6 +46,9 @@ Examples:

# Take only one screenshot
./Build/Scripts/runTests.sh -s screenshots Permissions/LimitToLanguages

# Test the example extension
./Build/Scripts/runTests.sh -s functional
EOF
}

Expand Down Expand Up @@ -157,6 +162,11 @@ case ${TEST_SUITE} in
${CONTAINER_BIN} run ${CONTAINER_COMMON_PARAMS} --name composer-install-${SUFFIX} -e COMPOSER_CACHE_DIR=.Build/.cache/composer ${IMAGE_PHP} "${COMMAND[@]}"
SUITE_EXIT_CODE=$?
;;
functional)
COMMAND=(.Build/bin/phpunit -c Build/phpunit/FunctionalTests.xml "$@")
${CONTAINER_BIN} run ${CONTAINER_COMMON_PARAMS} --name functional-${SUFFIX} -e typo3DatabaseDriver=pdo_sqlite ${IMAGE_PHP} "${COMMAND[@]}"
SUITE_EXIT_CODE=$?
;;
screenshots)
export PHP_RUN="${CONTAINER_BIN} run ${CONTAINER_COMMON_PARAMS} ${IMAGE_PHP}"
export WEB_START="${CONTAINER_BIN} run -d ${CONTAINER_COMMON_PARAMS} --name screenshots-web-${SUFFIX} ${IMAGE_PHP} php -S 0.0.0.0:8080 -t .Build/public Build/Screenshots/router.php"
Expand Down
27 changes: 27 additions & 0 deletions Build/phpunit/FunctionalTests.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?xml version="1.0"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/11.2/phpunit.xsd"
backupGlobals="true"
bootstrap="FunctionalTestsBootstrap.php"
cacheDirectory="../../.Build/.cache/phpunit"
colors="true"
displayDetailsOnTestsThatTriggerDeprecations="true"
displayDetailsOnTestsThatTriggerErrors="true"
displayDetailsOnTestsThatTriggerNotices="true"
displayDetailsOnTestsThatTriggerWarnings="true"
failOnDeprecation="true"
failOnNotice="true"
failOnRisky="true"
failOnWarning="true"
requireCoverageMetadata="false"
>
<testsuites>
<testsuite name="Functional tests">
<directory>../../Tests/Functional/</directory>
</testsuite>
</testsuites>
<php>
<ini name="display_errors" value="1"/>
<env name="TYPO3_CONTEXT" value="Testing"/>
</php>
</phpunit>
31 changes: 31 additions & 0 deletions Build/phpunit/FunctionalTestsBootstrap.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

/*
* This file is part of the TYPO3 CMS project.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
* of the License, or any later version.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*
* The TYPO3 project - inspiring people to share!
*/

/**
* Boilerplate for a functional test phpunit boostrap file.
*
* This file is loosely maintained within TYPO3 testing-framework, extensions
* are encouraged to not use it directly, but to copy it to an own place,
* usually in parallel to a FunctionalTests.xml file.
*
* This file is defined in FunctionalTests.xml and called by phpunit
* before instantiating the test suites.
*/
(static function () {
$testbase = new \TYPO3\TestingFramework\Core\Testbase();
$testbase->defineOriginalRootPath();
$testbase->createDirectory(ORIGINAL_ROOT . 'typo3temp/var/tests');
$testbase->createDirectory(ORIGINAL_ROOT . 'typo3temp/var/transient');
})();
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
<?php

return [
'ctrl' => [
'title' => 'my_extension.db:conference',
'label' => 'title',
'descriptionColumn' => 'internal_notes',
'default_sortby' => 'conference_date DESC',
'tstamp' => 'tstamp',
'crdate' => 'crdate',
'delete' => 'deleted',
'editlock' => 'editlock',
'enablecolumns' => [
'disabled' => 'hidden',
'starttime' => 'starttime',
'endtime' => 'endtime',
'fe_group' => 'fe_group',
],
'languageField' => 'sys_language_uid',
'transOrigPointerField' => 'l10n_parent',
'transOrigDiffSourceField' => 'l10n_diffsource',
'translationSource' => 'l10n_source',
'versioningWS' => true,
'origUid' => 't3_origuid',
'iconfile' => 'EXT:my_extension/Resources/Public/Icons/Conference.svg',
'security' => [
'ignorePageTypeRestriction' => true,
],
],
'columns' => [
'title' => [
'label' => 'my_extension.db:conference.title',
'config' => [
'type' => 'input',
'required' => true,
'max' => 255,
'eval' => 'trim',
],
],
'conference_date' => [
'label' => 'my_extension.db:conference.conference_date',
'config' => [
'type' => 'datetime',
'format' => 'date',
'required' => true,
],
],
'internal_notes' => [
'label' => 'my_extension.db:conference.internal_notes',
'config' => [
'type' => 'text',
'rows' => 3,
],
],
],
'types' => [
'0' => [
'showitem' => '
title, conference_date,
--div--;core.form.tabs:access,
hidden, --palette--;;access, fe_group, editlock,
--div--;core.form.tabs:language,
--palette--;;language,
--div--;core.form.tabs:notes,
internal_notes,
',
],
],
'palettes' => [
'access' => [
'label' => 'core.form.palettes:access',
'showitem' => 'starttime, endtime',
],
'language' => [
'showitem' => 'sys_language_uid, l10n_parent',
],
],
];
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
<file source-language="en" datatype="plaintext" original="EXT:my_extension/Resources/Private/Language/locallang_db.xlf" product-name="my_extension">
<header/>
<body>
<trans-unit id="conference" resname="conference">
<source>Conference</source>
</trans-unit>
<trans-unit id="conference.conference_date" resname="conference.conference_date">
<source>Date</source>
</trans-unit>
<trans-unit id="conference.internal_notes" resname="conference.internal_notes">
<source>Internal notes</source>
</trans-unit>
<trans-unit id="conference.title" resname="conference.title">
<source>Title</source>
</trans-unit>
</body>
</file>
</xliff>
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
18 changes: 18 additions & 0 deletions Documentation/CodeSnippets/my_extension/composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"name": "myvendor/my-extension",
"description": "Conference extension, the example extension of the Frontend Localization Guide",
"license": "GPL-2.0-or-later",
"type": "typo3-cms-extension",
"require": {
"typo3/cms-core": "^14.3"
},
"extra": {
"typo3/cms": {
"extension-key": "my_extension",
"version": "1.0.0",
"Package": {
"providesPackages": {}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
name: myvendor/my-sitepackage
label: 'My site package'
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
page = PAGE
page {
10 = PAGEVIEW
10 {
paths.10 = EXT:my_sitepackage/Resources/Private/Templates/

dataProcessing {
10 = menu
10 {
as = mainMenu
levels = 2
expandAll = 1
}

20 = language-menu
20 {
languages = auto
as = languagenavigation
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<f:render section="Main" />
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<f:layout name="Default" />

<f:section name="Main">
<header>
<f:if condition="{languagenavigation}">
<ul id="language_menu" class="language-menu">
<f:for each="{languagenavigation}" as="item">
<li class="{f:if(condition: item.active, then: 'active')} {f:if(condition: item.available, else: 'text-muted')}">
<f:if condition="{item.available}">
<f:then>
<a href="{item.link}" hreflang="{item.hreflang}" title="{item.title}">
<span>{item.navigationTitle}</span>
</a>
</f:then>
<f:else>
<span>{item.navigationTitle}</span>
</f:else>
</f:if>
</li>
</f:for>
</ul>
</f:if>
</header>
</f:section>
Loading
Loading