@webship.co/workspace-typo3 0.0.0-stage → 1.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,3 +1,145 @@
1
- # Temporary Holding Version
1
+ # @webship.co/workspace-typo3
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ TYPO3 for the [Webship Workspace](https://github.com/webship/workspace) dashboard: a builder
4
+ that makes a real TYPO3 site in a container, a typo3 console tool for the sites it built, the default
5
+ accounts, the [TYPO3 step pack](https://github.com/webship/typo3-steps) wired into the
6
+ workspace's testing setup, and two AI agents that know all of it.
7
+
8
+ The workspace is container-based (DDEV by default): a TYPO3 project is a row like any other, so
9
+ the row menus the core draws (start, stop, launch, backup, clone, remove, tests) work on it unchanged.
10
+
11
+ It is made from the reference platform plugin,
12
+ [`@webship.co/workspace-wordpress`](https://github.com/webship/workspace-wordpress).
13
+
14
+ ## Use it
15
+
16
+ ```bash
17
+ cd ~/workspace
18
+ bash core/scripts/plugins.sh --require github:webship/workspace-typo3 # npm install into the dashboard
19
+ bash core/scripts/plugins.sh --activate typo3 # plugins.typo3 in settings.yml
20
+ bash core/scripts/plugins.sh --install typo3 # commands, functions, args, agents
21
+ bash core/scripts/plugins.sh --configure typo3 # nothing to configure: it has no settings file
22
+ ```
23
+
24
+ The same four steps are buttons on the dashboard's **Settings → Plugins** page. `--install` is
25
+ idempotent. `--uninstall` removes what it placed; an agent you edited stays.
26
+
27
+ The commands land in the sites folders that are in the workspace (`dev`, `test`, `sandboxes`,
28
+ `demos`); the agents land in the AI Agents folder (`ai-agents/`) when the workspace has one, and are
29
+ installed into `~/.claude/agents` from there like any other agent.
30
+
31
+ It needs a Webship Workspace 1.0.7 or later.
32
+
33
+ ## What the package holds
34
+
35
+ | Path | What it is |
36
+ | --- | --- |
37
+ | `commands/cmd-typo3-project.sh` | The builder, in the Build list as **TYPO3 (13.4 LTS)**, installed into every sites folder |
38
+ | `commands/cmd-tools-typo3-cli.sh` | The typo3 console for one project: what the site is, a command, updates, caches, the default accounts |
39
+ | `scripts/functions/fun-typo3.sh` | The bash functions behind both, sourced by bootstrap once installed; the names the core's tools look for (`set_typo3_users`, `add_typo3_users`, `cancel_typo3_users`, `testing_configure_typo3`) |
40
+ | `scripts/args/arg-typo3.sh`, `arg-typo3-cli.sh` | Their argparse; the Build form draws the builder's flags from the first |
41
+ | `testing/site.feature` | The first feature a TYPO3 project gets when testing is set up |
42
+ | `agents/typo3-site-builder.md` | The agent that builds and maintains TYPO3 sites with these commands |
43
+ | `agents/typo3-tester.md` | The agent that writes and runs scenarios with the TYPO3 step pack |
44
+ | `src/index.ts` | `register(api)`: what the assistant is told about TYPO3 here |
45
+ | `features/typo3.feature` | Scenarios for the dashboard's own browser suite |
46
+
47
+ The `workspacePlugin` block in `package.json` is the manifest the installer reads.
48
+
49
+ ## The commands
50
+
51
+ Run them from a sites folder. `--help` is safe on both.
52
+
53
+ ### Build a site
54
+
55
+ ```bash
56
+ cd ~/workspace/dev
57
+ bash cmd-typo3-project.sh mysite --install --add-users
58
+ ```
59
+
60
+ | Flag | What it does |
61
+ | --- | --- |
62
+ | `--version <x>` | The release to create the project from, as a Composer constraint of `typo3/cms-base-distribution`: `^13.4` (the default, TYPO3 13.4 LTS), or a number such as `13.4.20` |
63
+ | `--install` | Set the site up, with the workspace account as its administrator, and add the official Introduction package: a site with pages, content and a search |
64
+ | `--add-users` | With `--install`: add the default accounts, an administrator and an editor |
65
+ | `--bare` | With `--install`: leave the Introduction package out (a backend, and no site or page yet) |
66
+ | `--php-version <x>` | The PHP of the project container (`8.3`) |
67
+ | `--launch` | Open the site when it is ready |
68
+
69
+ The site answers at `https://mysite.ddev.site`, the backend at `/typo3`. The build runs
70
+ `ddev config --project-type=typo3` with the docroot `public` and the Node.js of the workspace (24),
71
+ creates the project with Composer in the container (`typo3/cms-base-distribution`), and sets it up
72
+ with TYPO3's own `setup` command. The setup is given the container's database values
73
+ (`db` / `db` / `db`), the same in every project, and nothing personal. A project of the same name
74
+ is deleted first.
75
+
76
+ The Introduction package (`typo3/cms-introduction`, on the Bootstrap Package theme) is the site the
77
+ step pack is written for; with it the build also runs the upgrade wizard its search content needs
78
+ and points the search results at the templates of Indexed Search.
79
+
80
+ TYPO3 asks for an administrator password of 8 characters or more, with an upper and a lower case
81
+ letter, a digit and a sign: the setup stops when the workspace account's does not pass.
82
+
83
+ ### Work on a site
84
+
85
+ ```bash
86
+ bash cmd-tools-typo3-cli.sh mysite # version, address, sites, backend accounts
87
+ bash cmd-tools-typo3-cli.sh mysite --run "extension:list --active"
88
+ bash cmd-tools-typo3-cli.sh mysite --run "list" # every command of the console
89
+ bash cmd-tools-typo3-cli.sh mysite --flush # flush every cache
90
+ bash cmd-tools-typo3-cli.sh mysite --update # Composer packages, extension setup, caches
91
+ bash cmd-tools-typo3-cli.sh mysite --add-users # the default accounts
92
+ bash cmd-tools-typo3-cli.sh mysite --cancel-users # delete them
93
+ ```
94
+
95
+ ### The default accounts
96
+
97
+ | Account | Role | Handle in the tests |
98
+ | --- | --- | --- |
99
+ | `administrator` | administrator (not a system maintainer: the Extensions module and the Admin Tools stay with the workspace account) | `admin` |
100
+ | `editor` | the backend group "Advanced editors" (from the Introduction package) | `editor` |
101
+
102
+ Each has the address `<account>@example.com` and the password of the workspace's other default
103
+ lists. They are for local sites and for tests; the site's own administrator is the workspace
104
+ account and is never written into a test. The row's Users menu (**Add the test users**),
105
+ `bash cmd-tools-add-users.sh mysite typo3` and `bash cmd-tools-cancel-users.sh mysite typo3` add
106
+ and remove the same list. On a site without the Introduction package the editor is created without
107
+ a group.
108
+
109
+ ### Test a site
110
+
111
+ ```bash
112
+ bash cmd-tools-testing.sh mysite # webship-js, the step pack, the users registry, a first feature
113
+ bash cmd-tools-testing.sh mysite --run # run the suite in the container
114
+ bash cmd-tools-testing.sh mysite --run --path tests/features/site.feature
115
+ ```
116
+
117
+ `cmd-tools-testing.sh` is the workspace's own. For a TYPO3 project it also adds
118
+ `@webship-js/typo3-steps` to `package.json`, lists its step definitions in `cucumber.js` after
119
+ webship-js's own, writes the users registry (the handles above, overridable with
120
+ `TYPO3_<HANDLE>_USER` and `TYPO3_<HANDLE>_PASS`), places `tests/features/site.feature` when the
121
+ project has none, and makes sure the default accounts are on the site. Run it again and it adds what
122
+ is missing and keeps what you changed.
123
+
124
+ ## The agents
125
+
126
+ | Agent | Use it to |
127
+ | --- | --- |
128
+ | `typo3-site-builder` | Build, update, maintain or remove a TYPO3 site with the commands above, in containers only |
129
+ | `typo3-tester` | Set the testing stack up, look at the site in the Playwright MCP browser first, write scenarios from the pack's steps and run them; it never creates an account in a suite and never writes a platform name into a step phrase |
130
+
131
+ After `--install` they are in the AI Agents folder of the dashboard; **Install** there puts one into
132
+ `~/.claude/agents`, or from the command line:
133
+
134
+ ```bash
135
+ cd ~/workspace/ai-agents
136
+ bash cmd-tools-ai-items.sh typo3-tester --install
137
+ ```
138
+
139
+ ## Develop it
140
+
141
+ ```bash
142
+ npm install # builds dist/ (TypeScript)
143
+ npm run lint
144
+ npm test # the manifest, the commands, the agents, the functions against a scaffolded project
145
+ ```
@@ -0,0 +1,106 @@
1
+ ---
2
+ name: typo3-site-builder
3
+ description: Use this agent to build, maintain, update or remove a TYPO3 site in the Webship Workspace — a new site from `cmd-typo3-project.sh`, typo3 console work through `cmd-tools-typo3-cli.sh` (extensions, caches, upgrade wizards, updates, the default accounts), start, stop, backup and remove through the workspace's own tools. It works in containers only and never on the host. Invoke for "build a TYPO3 site", "add this extension to <site>", "update TYPO3 on <site>", "add the test accounts", or "remove the TYPO3 sandbox". For writing and running test scenarios, hand over to `typo3-tester`.
4
+ model: fable
5
+ tools:
6
+ - Bash
7
+ - Read
8
+ - Write
9
+ - Edit
10
+ - Glob
11
+ - Grep
12
+ ---
13
+
14
+ # typo3-site-builder
15
+
16
+ You build and look after TYPO3 sites in a Webship Workspace (`~/workspace`), a container-based
17
+ workspace (DDEV by default). Everything goes through the `cmd-*.sh` commands of a sites folder
18
+ (`dev/`, `test/`, `sandboxes/`, `demos/`) and through the project's container. The commands come from
19
+ the TYPO3 plugin (`@webship.co/workspace-typo3`); if a folder has no
20
+ `cmd-typo3-project.sh`, the plugin is not installed there: say so, and name the steps
21
+ (`bash core/scripts/plugins.sh --require @webship.co/workspace-typo3`, `--activate typo3`,
22
+ `--install typo3`) instead of working around it.
23
+
24
+ Read the command before quoting a flag: `bash <command> --help` is always safe.
25
+
26
+ ## Build a site
27
+
28
+ ```bash
29
+ cd ~/workspace/sandboxes # or dev, test, demos
30
+ bash cmd-typo3-project.sh mysite --install --add-users
31
+ ```
32
+
33
+ | Flag | What it does |
34
+ | --- | --- |
35
+ | `--version <x>` | The release to create the project from, as a Composer constraint of `typo3/cms-base-distribution`: `^13.4` (the default, TYPO3 13.4 LTS), or a number such as `13.4.20`. |
36
+ | `--install` | Sets TYPO3 up, with the workspace account (`account:` in `core/config/settings.yml`) as its administrator, and adds the official Introduction package: a site with pages, content and a search. Without it the code is there and the installer waits at `/typo3/install.php`. |
37
+ | `--add-users` | With `--install`: the default accounts, `administrator` (an administrator) and `editor` (in the backend group "Advanced editors"). |
38
+ | `--bare` | With `--install`: leaves the Introduction package out. The backend is there; there is no site and no page yet, so the front page answers with an error until you make one. |
39
+ | `--php-version <x>` | The PHP of the project container (`8.3` by default). |
40
+ | `--launch` | Opens the site when it is ready. |
41
+
42
+ The site answers at `https://<name>.ddev.site`, the backend at `/typo3`. It is a Composer project:
43
+ the docroot is `public/`, the configuration is in `config/`. The builder **deletes a project of the
44
+ same name first**: a build is a clean slate, so never point it at a site somebody still needs. The
45
+ name is a folder, a container project and a host name: short, lowercase, letters and digits.
46
+
47
+ TYPO3 asks for an administrator password of 8 characters or more, with an upper and a lower case
48
+ letter, a digit and a sign. When the workspace account's does not pass, the setup says so and the
49
+ build stops: do not invent another password, ask for the setting to be changed.
50
+
51
+ ## Work on a site
52
+
53
+ ```bash
54
+ bash cmd-tools-typo3-cli.sh mysite # what it is: version, address, sites, backend accounts
55
+ bash cmd-tools-typo3-cli.sh mysite --run "extension:list --active"
56
+ bash cmd-tools-typo3-cli.sh mysite --run "upgrade:list"
57
+ bash cmd-tools-typo3-cli.sh mysite --flush # every cache
58
+ bash cmd-tools-typo3-cli.sh mysite --update # the Composer packages, the extension setup, the caches
59
+ bash cmd-tools-typo3-cli.sh mysite --add-users # the default accounts
60
+ bash cmd-tools-typo3-cli.sh mysite --cancel-users # and away again
61
+ ```
62
+
63
+ `--run "list"` prints every command of the site's console. Inside the project folder,
64
+ `ddev exec vendor/bin/typo3 <command>` is the same console; an extension is a Composer package
65
+ (`ddev composer require <vendor>/<package>`, then `--run "extension:setup"`), and
66
+ `ddev export-db --file=…`, `ddev import-db --file=…` are the tools for the database.
67
+
68
+ The rest is the workspace's, the same for every project: `ddev start -y` and `ddev stop` in the
69
+ project (`stop` takes no `-y`), `bash cmd-tools-backup-<folder>.sh <name>`,
70
+ `bash cmd-tools-clone.sh <name> --to <new>`, `bash cmd-tools-remove.sh <name>`,
71
+ `bash cmd-tools-add-users.sh <name> typo3`, `bash cmd-tools-testing.sh <name>` (the testing
72
+ stack, with the TYPO3 step pack).
73
+
74
+ ## Rules
75
+
76
+ - **Containers only.** Never `php`, `composer`, `npm` or `mysql` on the host for a project.
77
+ - **The database values are the container's.** The setup is given `db` / `db` / `db` on the host
78
+ `db`, the same in every project, and the container tool writes its own `config/system/additional.php`.
79
+ Do not put another host, account or password into the configuration.
80
+ - **The administrator is the workspace account**, never a made-up one. Do not print its password,
81
+ do not write it into a file of the project, and do not put it in a test: the default accounts
82
+ exist for that.
83
+ - **Open-source only.** Extensions come from Packagist or the TYPO3 Extension Repository, as
84
+ Composer packages. No paid extension, no trial, no licence key, and no sign-in to any vendor
85
+ account.
86
+ - **Remove through the tool.** `bash cmd-tools-remove.sh <name>` takes the containers, the volumes
87
+ and the folder down together; `rm -rf` leaves the containers behind.
88
+ - **One build at a time**, and look at `free -g` before a build on a busy machine. A site you built
89
+ to try something is yours to clear: when the work is done, say what you made and offer to remove
90
+ it. Never delete unasked, and never leave it unmentioned.
91
+ - **Never restart the dashboard** or anything shared (the router, another project) to make your own
92
+ work go through.
93
+ - Say what you ran and what it printed. If a build fails, show the line that failed; do not retry
94
+ with different flags until something passes.
95
+
96
+ ## When something is off
97
+
98
+ | What you see | What it is |
99
+ | --- | --- |
100
+ | `composer create-project … failed` | No network in the container, or a constraint no release matches: the default `^13.4` proves which. |
101
+ | `typo3 setup failed` | Most often the workspace account's password does not pass TYPO3's rules (8 characters, both cases, a digit, a sign): it is changed in `core/config/settings.yml`, by its owner. |
102
+ | The installer instead of the backend | The build ran without `--install`: finish it at `/typo3/install.php`, or build again with `--install`. |
103
+ | An error page on the front page, the backend works | The site was built with `--bare`: it has no site configuration and no page yet. |
104
+ | A page shows old content | The caches: `bash cmd-tools-typo3-cli.sh <name> --flush`. |
105
+ | `The site has no backend group "Advanced editors"` | The accounts were added to a site without the Introduction package: `editor` exists, with no rights until you give it a group. |
106
+ | `is not a TYPO3 project` from the CLI tool | The project's `.ddev/config.yaml` does not say `type: typo3`: it was not built by this builder. |
@@ -0,0 +1,125 @@
1
+ ---
2
+ name: typo3-tester
3
+ description: Use this agent to test a TYPO3 site of the Webship Workspace with webship-js and the TYPO3 step pack (`@webship-js/typo3-steps`) — set the testing stack up with `cmd-tools-testing.sh`, explore the site in the Playwright MCP browser first, write Gherkin scenarios from the pack's own steps, run them in the project's container and read the report. It logs in by the handles of the users registry, never creates an account in a suite, and never writes a platform name into a step phrase. Invoke for "test this TYPO3 site", "write scenarios for the editor", "why does this scenario fail", or "run the suite on <site>". For building or changing the site itself, hand over to `typo3-site-builder`.
4
+ model: fable
5
+ tools:
6
+ - Bash
7
+ - Read
8
+ - Write
9
+ - Edit
10
+ - Glob
11
+ - Grep
12
+ - mcp__playwright__browser_navigate
13
+ - mcp__playwright__browser_snapshot
14
+ - mcp__playwright__browser_click
15
+ - mcp__playwright__browser_type
16
+ - mcp__playwright__browser_evaluate
17
+ - mcp__playwright__browser_tabs
18
+ - mcp__playwright__browser_take_screenshot
19
+ ---
20
+
21
+ # typo3-tester
22
+
23
+ You test TYPO3 sites in a Webship Workspace (`~/workspace`) with
24
+ [webship-js](https://github.com/webship/webship-js) (Playwright and Cucumber) and its TYPO3 step
25
+ pack, [`@webship-js/typo3-steps`](https://github.com/webship/typo3-steps). The suite lives in
26
+ the project (`cucumber.js`, `tests/features/`, `tests/step-definitions/`) and runs in the project's
27
+ container.
28
+
29
+ ## Set the stack up
30
+
31
+ ```bash
32
+ cd ~/workspace/test # the sites folder the project is in
33
+ bash cmd-tools-testing.sh mysite # webship-js, the step pack, the users registry, a first feature
34
+ ```
35
+
36
+ For a TYPO3 project the setup adds the pack to `package.json`, lists its step definitions in
37
+ `cucumber.js` after webship-js's own, writes the users registry and `tests/features/site.feature`,
38
+ and makes sure the default accounts are on the site. It is idempotent: run it again and it adds
39
+ what is missing, and keeps what you changed.
40
+
41
+ ## The order of work
42
+
43
+ 1. **Read the installed steps.** They are the source of truth, not memory:
44
+ ```bash
45
+ ls node_modules/@webship-js/typo3-steps/tests/step-definitions/
46
+ grep -n "^\(Given\|When\|Then\)" node_modules/@webship-js/typo3-steps/tests/step-definitions/typo3-backend.steps.js
47
+ ```
48
+ Each step carries a JSDoc block with examples. webship-js's own steps (status codes, classes,
49
+ landmarks, accessibility) are in `node_modules/webship-js/tests/step-definitions/`.
50
+ 2. **Look at the site in the Playwright MCP browser first**, in a tab of your own: open the page,
51
+ take a snapshot, do the thing by hand once. A scenario written without having seen the page
52
+ asserts what you imagine. Close your tab when you are done; leave other tabs alone.
53
+ 3. **Write the scenario** from steps that exist. Run a dry run before a real one:
54
+ ```bash
55
+ bash cmd-tools-testing.sh mysite --dry-run # every step matches one definition, no browser
56
+ ```
57
+ 4. **Run it**, narrow first, then the whole suite:
58
+ ```bash
59
+ bash cmd-tools-testing.sh mysite --run --path tests/features/site.feature
60
+ bash cmd-tools-testing.sh mysite --run --tags "@critical"
61
+ bash cmd-tools-testing.sh mysite --run
62
+ ```
63
+ 5. **Read the result**: `tests/reports/cucumber_report.html`, the screenshot and the page dump of a
64
+ failed step in `tests/screenshots/`. Report what failed and why, not only that it failed.
65
+
66
+ ## Accounts
67
+
68
+ A scenario logs in to the backend by a **handle** of the users registry (`worldParameters.users` in
69
+ `cucumber.js`):
70
+
71
+ ```gherkin
72
+ Given I am a logged in user with the "editor" user
73
+ Then I should be logged in as "editor"
74
+ ```
75
+
76
+ | Handle | Account | Role |
77
+ | --- | --- | --- |
78
+ | `admin` | `administrator` | administrator (not a system maintainer: no Extensions module, no Admin Tools) |
79
+ | `editor` | `editor` | the backend group "Advanced editors" of the Introduction package |
80
+
81
+ These are the default accounts (`bash cmd-tools-typo3-cli.sh mysite --add-users`). Override one
82
+ for another environment with `TYPO3_<HANDLE>_USER` and `TYPO3_<HANDLE>_PASS`.
83
+
84
+ ## Rules
85
+
86
+ - **Never create an account in a suite.** No `backend:user:create` in a hook, no scenario that
87
+ leaves an account behind, no step that adds one. Accounts are configuration: they are on the
88
+ site before the suite runs. If a scenario needs a role the registry does not have, say so and ask
89
+ for the account to be added to the site and to the registry.
90
+ - **Never the workspace account.** The site's own administrator (the workspace account) is not in
91
+ the registry and its password goes in no file. `admin` in the registry is the `administrator`
92
+ default account.
93
+ - **No password in a feature file**, except where a wrong password is the subject of the scenario.
94
+ - **No platform name in a step phrase.** A step says what a person does or sees: `I am a logged in
95
+ user with the "editor" user`, `I open the "Page" module`, `I select the "Home" page in the page
96
+ tree`. Never a phrase with the platform's name in it. The same holds for a custom step you write.
97
+ - **No CSS selector and no address in a scenario when a step of the pack says it.** `the "List"
98
+ module`, not `/typo3/module/web/list`.
99
+ - **A custom step is the last resort.** Look in the pack and in webship-js first. If one is really
100
+ missing, write it in `tests/step-definitions/`, with a JSDoc block and examples like the pack's,
101
+ and say that it may belong upstream.
102
+ - **Content a scenario creates, it removes**, or it names it so a later run finds and clears it. A
103
+ suite leaves the site as it found it.
104
+ - **Everything runs in the container.** Never `npx cucumber-js` or `npx playwright` on the host for
105
+ a project.
106
+ - **A failing suite is a result.** Do not tag a scenario `@wip`, raise a timeout or loosen an
107
+ assertion to make a run green. Say what the site did.
108
+
109
+ The pack's own features are written for the Introduction package (its pages, menus and copy). A
110
+ site built with `--bare`, or one with other content, needs its own page names in the scenarios.
111
+
112
+ ## A scenario, the way the pack reads
113
+
114
+ ```gherkin
115
+ Feature: An editor works in the page module
116
+
117
+ Scenario: The editor opens the page module
118
+ Given I am a logged in user with the "editor" user
119
+ When I open the "Page" module
120
+ Then the "Page" module should be active
121
+ And I should not see the "Extensions" module
122
+ ```
123
+
124
+ Check every phrase against the installed definitions before you run it: the pack moves, and a phrase
125
+ from memory is a guess.
@@ -0,0 +1,26 @@
1
+ #!/usr/bin/env bash
2
+
3
+ # Installed by the TYPO3 plugin (plugins.sh --install typo3); __WORKSPACE__ is the workspace it was installed into.
4
+ #
5
+ # The typo3 console (vendor/bin/typo3) for one TYPO3 project of this workspace, in its container:
6
+ # say what the site is, run a console command, update the packages, flush the caches, add or
7
+ # remove the default accounts. Nothing here runs on the host.
8
+
9
+ # Bootstrap.
10
+ # Find the workspace tooling from this script, so a fresh clone needs no setup.
11
+ WORKSPACE_SCRIPTS="${WORKSPACE_SCRIPTS:-$(cd "$(dirname "${BASH_SOURCE[0]}")/../core/scripts" && pwd)}";
12
+ source ${WORKSPACE_SCRIPTS}/bootstrap.sh || exit 1 ;
13
+
14
+ # Load workspace settings.
15
+ eval $(parse_yaml ${WORKSPACE_CONFIG}/workspace.__WORKSPACE__.settings.yml);
16
+
17
+ # Distribution.
18
+ distribution_name="typo3";
19
+
20
+ ARGPARSE_DESCRIPTION="Run the typo3 console on a TYPO3 project of __WORKSPACE__: status, a command, updates, caches, the default accounts"
21
+ # The args file comes with the plugin: core/scripts/plugins/typo3/ is where plugins.sh --install puts it.
22
+ source ${WORKSPACE_SCRIPTS}/plugins/typo3/args/arg-typo3-cli.sh || exit 1 ;
23
+
24
+ shift $#;
25
+
26
+ typo3_cli_tool ;
@@ -0,0 +1,35 @@
1
+ #!/usr/bin/env bash
2
+
3
+ # workspace-name: TYPO3 (13.4 LTS)
4
+
5
+ # Installed by the TYPO3 plugin (plugins.sh --install typo3); __WORKSPACE__ is the workspace it was installed into.
6
+ #
7
+ # Build a TYPO3 site in a container: TYPO3 13.4 LTS, or the release --version names, at
8
+ # https://<name>.ddev.site. With --install the site is set up with the workspace account as its
9
+ # administrator and gets the official Introduction package (a site with pages and content); with
10
+ # --add-users it also gets the default accounts, an administrator and an editor.
11
+
12
+ # Bootstrap.
13
+ # Find the workspace tooling from this script, so a fresh clone needs no setup.
14
+ WORKSPACE_SCRIPTS="${WORKSPACE_SCRIPTS:-$(cd "$(dirname "${BASH_SOURCE[0]}")/../core/scripts" && pwd)}";
15
+ source ${WORKSPACE_SCRIPTS}/bootstrap.sh || exit 1 ;
16
+
17
+ # Load workspace settings.
18
+ eval $(parse_yaml ${WORKSPACE_CONFIG}/workspace.__WORKSPACE__.settings.yml);
19
+
20
+ # Set site version.
21
+ site_version="^13.4";
22
+
23
+ # Distribution.
24
+ distribution_name="typo3";
25
+ distribution_title="TYPO3";
26
+ distribution_webroot="public";
27
+ project_template="typo3/cms-base-distribution";
28
+
29
+ ARGPARSE_DESCRIPTION="Build a ${distribution_title} project in __WORKSPACE__"
30
+ # The args file comes with the plugin: core/scripts/plugins/typo3/ is where plugins.sh --install puts it.
31
+ source ${WORKSPACE_SCRIPTS}/plugins/typo3/args/arg-typo3.sh || exit 1 ;
32
+
33
+ shift $#;
34
+
35
+ typo3_build ;
@@ -0,0 +1,22 @@
1
+ /**
2
+ * TYPO3 for Webship Workspace: a platform plugin.
3
+ *
4
+ * What the package carries is placed by the installer from the manifest: the builder and the
5
+ * typo3 console tool in the sites folders, their functions and argparse under core/scripts/plugins/typo3/,
6
+ * the agents in the AI Agents folder. The dashboard needs nothing drawn for it: the builder is in the
7
+ * Build list because it is a cmd-*-project.sh, the row menus are the core's, the agents are listed
8
+ * like any other. What register() adds is what the assistant is told.
9
+ *
10
+ * Everything the dashboard is asked for goes through `api`; this package requires nothing from the
11
+ * dashboard's own files, so it can be installed from npm and removed without a trace.
12
+ */
13
+ import type { PluginApi } from '@webship.co/workspace-plugin-api';
14
+ /** The plugin's name, which is also the DDEV project type its functions are named after. */
15
+ export declare const PLATFORM = "typo3";
16
+ /** The commands the installer places in every sites folder. */
17
+ export declare const COMMANDS: string[];
18
+ /** The agents the installer places in the AI Agents folder. */
19
+ export declare const AGENTS: string[];
20
+ /** What the assistant is told about TYPO3 in this workspace. */
21
+ export declare function assistantContext(): string;
22
+ export declare function register(api: PluginApi): void;
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+ /**
3
+ * TYPO3 for Webship Workspace: a platform plugin.
4
+ *
5
+ * What the package carries is placed by the installer from the manifest: the builder and the
6
+ * typo3 console tool in the sites folders, their functions and argparse under core/scripts/plugins/typo3/,
7
+ * the agents in the AI Agents folder. The dashboard needs nothing drawn for it: the builder is in the
8
+ * Build list because it is a cmd-*-project.sh, the row menus are the core's, the agents are listed
9
+ * like any other. What register() adds is what the assistant is told.
10
+ *
11
+ * Everything the dashboard is asked for goes through `api`; this package requires nothing from the
12
+ * dashboard's own files, so it can be installed from npm and removed without a trace.
13
+ */
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.AGENTS = exports.COMMANDS = exports.PLATFORM = void 0;
16
+ exports.assistantContext = assistantContext;
17
+ exports.register = register;
18
+ /** The plugin's name, which is also the DDEV project type its functions are named after. */
19
+ exports.PLATFORM = 'typo3';
20
+ /** The commands the installer places in every sites folder. */
21
+ exports.COMMANDS = ['cmd-typo3-project.sh', 'cmd-tools-typo3-cli.sh'];
22
+ /** The agents the installer places in the AI Agents folder. */
23
+ exports.AGENTS = ['typo3-site-builder', 'typo3-tester'];
24
+ /** What the assistant is told about TYPO3 in this workspace. */
25
+ function assistantContext() {
26
+ return [
27
+ 'TYPO3 (a plugin, @webship.co/workspace-typo3): a TYPO3 site is built with',
28
+ '`bash cmd-typo3-project.sh <name> --install --add-users` from a sites folder (dev, test, sandboxes, demos),',
29
+ 'in a container like every other project, at https://<name>.ddev.site (the backend at /typo3); --install sets TYPO3 13.4 LTS up',
30
+ 'with the Introduction package (a site with pages and content), --bare leaves that package out.',
31
+ '`bash cmd-tools-typo3-cli.sh <name>` says what the site is; `--run "<command>"` runs the typo3 console (vendor/bin/typo3) in it,',
32
+ '`--update` updates the Composer packages, `--flush` flushes the caches, `--add-users` adds the default accounts (an administrator and an editor).',
33
+ '`bash cmd-tools-testing.sh <name>` sets up webship-js with the TYPO3 step pack; `--run` runs the suite.',
34
+ `For TYPO3 work, hand over to the agents ${exports.AGENTS.map((a) => `\`${a}\``).join(' and ')}.`,
35
+ 'Never run php, composer, npm or mysql on the host for a project.',
36
+ ].join(' ');
37
+ }
38
+ function register(api) {
39
+ api.addAssistantContext(assistantContext);
40
+ }
41
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;GAWG;;;AAcH,4CAYC;AAED,4BAEC;AA1BD,4FAA4F;AAC/E,QAAA,QAAQ,GAAG,OAAO,CAAC;AAEhC,+DAA+D;AAClD,QAAA,QAAQ,GAAG,CAAC,sBAAsB,EAAE,wBAAwB,CAAC,CAAC;AAE3E,+DAA+D;AAClD,QAAA,MAAM,GAAG,CAAC,oBAAoB,EAAE,cAAc,CAAC,CAAC;AAE7D,gEAAgE;AAChE,SAAgB,gBAAgB;IAC9B,OAAO;QACL,2EAA2E;QAC3E,6GAA6G;QAC7G,gIAAgI;QAChI,gGAAgG;QAChG,kIAAkI;QAClI,mJAAmJ;QACnJ,yGAAyG;QACzG,2CAA2C,cAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG;QACzF,kEAAkE;KACnE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACd,CAAC;AAED,SAAgB,QAAQ,CAAC,GAAc;IACrC,GAAG,CAAC,mBAAmB,CAAC,gBAAgB,CAAC,CAAC;AAC5C,CAAC"}
@@ -0,0 +1,17 @@
1
+ Feature: The TYPO3 plugin on the dashboard
2
+ Once the plugin is activated and installed, the sites folders offer the TYPO3 builder, the
3
+ AI Agents folder lists the TYPO3 agents, and the Plugins page lists the plugin with its steps.
4
+
5
+ Scenario: The plugin is listed on the Plugins page
6
+ Given I am on "/settings/plugins"
7
+ Then I should see "TYPO3"
8
+ And I should see "@webship.co/workspace-typo3"
9
+
10
+ Scenario: A sites folder offers the TYPO3 builder
11
+ Given I am on "/dev"
12
+ Then "option[value='cmd-typo3-project.sh']" should be attached
13
+
14
+ Scenario: The AI Agents folder lists the agents the plugin ships
15
+ Given I am on "/ai-agents"
16
+ Then I should see "typo3-site-builder"
17
+ And I should see "typo3-tester"
package/package.json CHANGED
@@ -1,6 +1,75 @@
1
1
  {
2
2
  "name": "@webship.co/workspace-typo3",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "1.0.7",
4
+ "description": "TYPO3 for Webship Workspace: the builder (`cmd-typo3-project.sh`) and the typo3 console tool in every sites folder, the default accounts, the TYPO3 step pack wired into the testing setup, and two AI agents in the AI Agents folder.",
5
+ "main": "dist/src/index.js",
6
+ "types": "dist/src/index.d.ts",
7
+ "license": "ISC",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "https://github.com/webship/workspace-typo3.git"
11
+ },
12
+ "files": [
13
+ "dist/src",
14
+ "agents",
15
+ "commands",
16
+ "features",
17
+ "scripts",
18
+ "testing",
19
+ "README.md"
20
+ ],
21
+ "scripts": {
22
+ "build": "tsc -p tsconfig.json",
23
+ "prepare": "npm run build",
24
+ "test": "npm run build && node --test dist/tests/*.test.js",
25
+ "lint": "tsc -p tsconfig.json --noEmit"
26
+ },
27
+ "workspacePlugin": {
28
+ "name": "typo3",
29
+ "label": "TYPO3",
30
+ "commands": {
31
+ "types": [
32
+ "sites"
33
+ ],
34
+ "workspaces": [
35
+ "dev",
36
+ "test",
37
+ "sandboxes",
38
+ "demos"
39
+ ],
40
+ "files": [
41
+ "commands/cmd-typo3-project.sh",
42
+ "commands/cmd-tools-typo3-cli.sh"
43
+ ]
44
+ },
45
+ "scripts": {
46
+ "functions": [
47
+ "scripts/functions/fun-typo3.sh"
48
+ ],
49
+ "args": [
50
+ "scripts/args/arg-typo3.sh",
51
+ "scripts/args/arg-typo3-cli.sh"
52
+ ],
53
+ "machine": [
54
+ "testing/site.feature"
55
+ ]
56
+ },
57
+ "ai": {
58
+ "agents": [
59
+ "agents/typo3-site-builder.md",
60
+ "agents/typo3-tester.md"
61
+ ]
62
+ },
63
+ "features": [
64
+ "features/typo3.feature"
65
+ ]
66
+ },
67
+ "devDependencies": {
68
+ "@types/node": "^24.0.0",
69
+ "@webship.co/workspace-plugin-api": "^1.0.7",
70
+ "typescript": "^5.9.0"
71
+ },
72
+ "publishConfig": {
73
+ "access": "public"
74
+ }
75
+ }
@@ -0,0 +1,25 @@
1
+ #!/usr/bin/env bash
2
+
3
+ argparse "$@" <<ARGEOF || exit 1
4
+ parser.add_argument('PROJECT_NAME',
5
+ help='The TYPO3 project in this workspace.')
6
+ parser.add_argument('-r', '--run',
7
+ default="_none_",
8
+ help='A typo3 console command to run in the project, without the leading typo3. Example: --run "extension:list --active"')
9
+ parser.add_argument('-u', '--update',
10
+ action='store_true',
11
+ default=False,
12
+ help='Update the Composer packages of the project (TYPO3 and its extensions) within their constraints, set the extensions up and flush the caches.')
13
+ parser.add_argument('-f', '--flush',
14
+ action='store_true',
15
+ default=False,
16
+ help='Flush every cache, and nothing else.')
17
+ parser.add_argument('-a', '--add-users',
18
+ action='store_true',
19
+ default=False,
20
+ help='Add the default accounts, an administrator and an editor. An account that is already there is left as it is.')
21
+ parser.add_argument('-c', '--cancel-users',
22
+ action='store_true',
23
+ default=False,
24
+ help='Delete the default accounts.')
25
+ ARGEOF
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env bash
2
+
3
+ argparse "$@" <<ARGEOF || exit 1
4
+ parser.add_argument('PROJECT_NAME',
5
+ help='The name of the project: its folder, its DDEV project and its host name.')
6
+ parser.add_argument('-v', '--version',
7
+ default="${site_version}",
8
+ help='The TYPO3 release to create the project from, as a Composer constraint of typo3/cms-base-distribution. Example: --version 13.4.20 [default %(default)s]')
9
+ parser.add_argument('-i', '--install',
10
+ action='store_true',
11
+ default=False,
12
+ help='Set TYPO3 up, with the workspace account as the administrator, and add the Introduction package: a site with pages and content.')
13
+ parser.add_argument('-a', '--add-users',
14
+ action='store_true',
15
+ default=False,
16
+ help='With --install, add the default accounts: an administrator and an editor, the ones the test scenarios log in as.')
17
+ parser.add_argument('-b', '--bare',
18
+ action='store_true',
19
+ default=False,
20
+ help='With --install, leave the Introduction package out: an installation with a backend, and no site or page yet.')
21
+ parser.add_argument('-l', '--launch',
22
+ action='store_true',
23
+ default=False,
24
+ help='Open the site in a browser when it is ready.')
25
+ parser.add_argument('--php-version',
26
+ default="8.3",
27
+ choices=['8.4', '8.3', '8.2'],
28
+ help='PHP version for the project container. Example: --php-version 8.4 [default %(default)s]')
29
+ ARGEOF
@@ -0,0 +1,358 @@
1
+ #!/usr/bin/env bash
2
+
3
+ # TYPO3 for the Webship Workspace: build a site, run the typo3 console on it, add its default
4
+ # accounts, and wire its step pack into the testing setup.
5
+ #
6
+ # Placed by `plugins.sh --install typo3` in core/scripts/plugins/typo3/functions/, where
7
+ # bootstrap sources it after the core's own functions. Everything runs in the project's container
8
+ # (DDEV by default: `ddev composer …`, `ddev exec vendor/bin/typo3 …`), never on the host. The
9
+ # setup command is given the container's own database values (db / db / db) and nothing personal.
10
+ #
11
+ # Four names are the ones the core's tools look for, under the DDEV project type `typo3`:
12
+ # set_typo3_users the default accounts (cmd-tools-add-users.sh <project> typo3)
13
+ # add_typo3_users create them with the console (the same tool, and --add-users of the builder)
14
+ # cancel_typo3_users delete them (cmd-tools-cancel-users.sh <project> typo3)
15
+ # testing_configure_typo3 the step pack in the testing stack (cmd-tools-testing.sh <project>)
16
+
17
+ # The step pack a TYPO3 project is tested with, and the release line it is required at.
18
+ readonly TYPO3_STEPS_PACKAGE='@webship-js/typo3-steps';
19
+ readonly TYPO3_STEPS_VERSION='^2.1.0';
20
+
21
+ # The backend group the editor account joins: the one the Introduction package brings.
22
+ readonly TYPO3_EDITOR_GROUP='Advanced editors';
23
+
24
+ # The default accounts: an administrator and an editor, the ones a scenario logs in as. Accounts
25
+ # are configuration, created once on the site; a test suite never creates or deletes one. The
26
+ # role is `admin` for an administrator, or the title of a backend group.
27
+ function set_typo3_users() {
28
+ users=(administrator editor);
29
+ local roles=('admin' "${TYPO3_EDITOR_GROUP}") i user ;
30
+ for i in "${!users[@]}" ; do
31
+ user="${users[$i]}" ;
32
+ printf -v "user_${user}_name" '%s' "${user}" ;
33
+ printf -v "user_${user}_mail" '%s' "${user}@example.com" ;
34
+ printf -v "user_${user}_password" '%s' 'dD.123123ddd' ;
35
+ printf -v "user_${user}_role" '%s' "${roles[$i]}" ;
36
+ done
37
+ }
38
+
39
+ # Is this folder a TYPO3 project? Its DDEV project type says so.
40
+ function typo3_is_project() {
41
+ local project_path="$1";
42
+ grep -qE '^type:[[:space:]]*"?typo3"?[[:space:]]*$' "${project_path}/.ddev/config.yaml" 2>/dev/null ;
43
+ }
44
+
45
+ # Is the site set up? The setup command writes config/system/settings.php, and nothing else does.
46
+ function typo3_is_installed() {
47
+ [ -f "$1/config/system/settings.php" ] ;
48
+ }
49
+
50
+ # Go to the project a tool was asked about, or say why not.
51
+ function typo3_enter_project() {
52
+ local project_path="${WORKSPACE_ROOT}/${doc_name}/${PROJECT_NAME}";
53
+ if [ ! -d "${project_path}" ] ; then
54
+ echo "No project ${PROJECT_NAME} in ${WORKSPACE_ROOT}/${doc_name}." ;
55
+ return 1 ;
56
+ fi
57
+ if ! typo3_is_project "${project_path}" ; then
58
+ echo "${doc_name}/${PROJECT_NAME} is not a TYPO3 project (its .ddev/config.yaml does not say type: typo3)." ;
59
+ return 1 ;
60
+ fi
61
+ cd "${project_path}" || return 1 ;
62
+ }
63
+
64
+ # Run the typo3 console in the container of the project the shell is in. Every argument is
65
+ # quoted for the container's shell, so a password with a sign in it arrives as one argument.
66
+ function typo3_cli() {
67
+ local line="vendor/bin/typo3" arg ;
68
+ for arg in "$@" ; do
69
+ line="${line} $(printf '%q' "${arg}")" ;
70
+ done
71
+ ddev exec "${line}" ;
72
+ }
73
+
74
+ # One value from the project's database, read in its container.
75
+ function typo3_query() {
76
+ ddev mysql -N -B -e "$1" 2>/dev/null | tr -d '\r' | head -1 ;
77
+ }
78
+
79
+ # Is there a backend account of this username on the site?
80
+ function typo3_user_exists() {
81
+ [ "$(typo3_query "SELECT COUNT(*) FROM be_users WHERE username = '$1' AND deleted = 0")" == '1' ] ;
82
+ }
83
+
84
+ # Build a TYPO3 site from nothing: the container, the code, and with --install the site itself.
85
+ function typo3_build() {
86
+ trim_project_name ;
87
+ local base_url="https://${PROJECT_NAME}.ddev.site" ;
88
+ local version="${VERSION:-${site_version:-^13.4}}" ;
89
+ local php_version="${PHP_VERSION:-${site_php_version:-8.3}}" ;
90
+
91
+ cd ${WORKSPACE_ROOT}/${doc_name} || exit 1 ;
92
+
93
+ drop_database ;
94
+ rm -rf "${PROJECT_NAME}" ;
95
+ mkdir -p "${PROJECT_NAME}" ;
96
+ cd ${WORKSPACE_ROOT}/${doc_name}/${PROJECT_NAME} || exit 1 ;
97
+
98
+ ddev config --project-type=typo3 --docroot="${distribution_webroot}" --project-name=${PROJECT_NAME} \
99
+ --php-version=${php_version} --nodejs-version=$(ddev_nodejs_version) --auto || exit 1 ;
100
+ ddev_up start -y || exit 1 ;
101
+
102
+ ddev composer create-project "${project_template}:${version}" . --no-interaction \
103
+ || { echo "composer create-project ${project_template}:${version} failed." ; exit 1 ; } ;
104
+
105
+ if [ "${INSTALL}" == 'yes' ] ; then
106
+ # The container's own database values, the same in every project: nothing personal is written.
107
+ typo3_cli setup --no-interaction --force --server-type=other \
108
+ --driver=mysqli --host=db --port=3306 --dbname=db --username=db --password=db \
109
+ --admin-username="${account_name}" --admin-user-password="${account_pass}" --admin-email="${account_mail}" \
110
+ --project-name="${doc_name} ${PROJECT_NAME}" \
111
+ || { echo "typo3 setup failed. TYPO3 asks for an administrator password of 8 characters or more, with an upper and a lower case letter, a digit and a sign: see account: pass in core/config/settings.yml." ; exit 1 ; } ;
112
+
113
+ if [ "${BARE}" == 'yes' ] ; then
114
+ echo "No Introduction package: the installation has no site and no page yet." ;
115
+ else
116
+ typo3_introduction || exit 1 ;
117
+ fi
118
+
119
+ if [ "${ADD_USERS}" == 'yes' ] ; then
120
+ set_typo3_users ;
121
+ add_typo3_users ;
122
+ cd ${WORKSPACE_ROOT}/${doc_name}/${PROJECT_NAME} || exit 1 ;
123
+ fi
124
+
125
+ typo3_cli cache:flush ;
126
+
127
+ echo "${doc_name} ${PROJECT_NAME} has been installed: $(typo3_cli --version 2>/dev/null | head -1).";
128
+ echo "Go to ${base_url}/typo3 and log in as ${account_name}";
129
+ else
130
+ [ "${ADD_USERS}" == 'yes' ] && echo "--add-users needs --install: there is no site to add accounts to yet." ;
131
+ echo "${doc_name} ${PROJECT_NAME} is ready to install.";
132
+ echo "Go to ${base_url}/typo3/install.php";
133
+ fi
134
+
135
+ if [ "${LAUNCH}" == 'yes' ] ; then
136
+ ddev launch ;
137
+ fi
138
+
139
+ cd ${WORKSPACE_ROOT}/${doc_name};
140
+ }
141
+
142
+ # The official Introduction package (typo3/cms-introduction, on the Bootstrap Package theme): a
143
+ # site with pages, content, a search and the backend groups the editor account joins. It is the
144
+ # site the step pack is written for.
145
+ function typo3_introduction() {
146
+ echo "Adding the Introduction package." ;
147
+ ddev composer require typo3/cms-introduction --no-interaction \
148
+ || { echo "composer require typo3/cms-introduction failed." ; return 1 ; } ;
149
+
150
+ # Activates the package and imports its content and its site configuration.
151
+ typo3_cli extension:setup || return 1 ;
152
+
153
+ # The content stores the search as a plugin of the old kind, and the setup marks every upgrade
154
+ # wizard as done before the content is imported: run the one that turns it into a content element.
155
+ typo3_cli upgrade:mark:undone indexedSearchCTypeMigration ;
156
+ typo3_cli upgrade:run indexedSearchCTypeMigration --no-interaction ;
157
+
158
+ # The search result templates of the theme call a ViewHelper TYPO3 13.4 no longer ships, which
159
+ # breaks the result list: use the templates of Indexed Search itself.
160
+ ddev mysql -e "UPDATE sys_template SET config = CONCAT(IFNULL(config, ''), '
161
+ plugin.tx_indexedsearch.view.templateRootPaths.20 >
162
+ plugin.tx_indexedsearch.view.templateRootPaths.21 >
163
+ plugin.tx_indexedsearch.view.partialRootPaths.20 >
164
+ plugin.tx_indexedsearch.view.partialRootPaths.21 >
165
+ plugin.tx_indexedsearch.view.layoutRootPaths.20 >
166
+ plugin.tx_indexedsearch.view.layoutRootPaths.21 >
167
+ ') WHERE root = 1 AND (config IS NULL OR config NOT LIKE '%plugin.tx_indexedsearch.view.templateRootPaths.20 >%')" ;
168
+ }
169
+
170
+ # Create the default accounts with the typo3 console. An account that is already there is left as it is.
171
+ # The list is loaded by the caller (set_typo3_users): the core's add_users, the builder, the CLI tool.
172
+ function add_typo3_users() {
173
+ typo3_enter_project || return 1 ;
174
+ local user user_name user_mail user_password user_role group ;
175
+ for user in "${users[@]}" ; do
176
+ user_name="user_${user}_name"; user_mail="user_${user}_mail";
177
+ user_password="user_${user}_password"; user_role="user_${user}_role";
178
+
179
+ echo " ---------------------------------------------------------------- ";
180
+ echo " User name: ${!user_name}";
181
+ echo " User mail: ${!user_mail}";
182
+ echo " User password: ${!user_password}";
183
+ echo " User role: ${!user_role}";
184
+ echo " ================================================================= ";
185
+
186
+ if typo3_user_exists "${!user_name}" ; then
187
+ echo " ${!user_name} is already there." ;
188
+ elif [ "${!user_role}" == 'admin' ] ; then
189
+ typo3_cli backend:user:create --no-interaction --username="${!user_name}" \
190
+ --password="${!user_password}" --email="${!user_mail}" --admin && echo " ${!user_name} is created." ;
191
+ else
192
+ # A backend group is named by its number: look it up by its title.
193
+ group="$(typo3_query "SELECT uid FROM be_groups WHERE title = '${!user_role}' AND deleted = 0 LIMIT 1")" ;
194
+ if [ -z "${group}" ] ; then
195
+ echo " The site has no backend group \"${!user_role}\" (the Introduction package brings it): ${!user_name} is created without a group." ;
196
+ typo3_cli backend:user:create --no-interaction --username="${!user_name}" \
197
+ --password="${!user_password}" --email="${!user_mail}" && echo " ${!user_name} is created." ;
198
+ else
199
+ typo3_cli backend:user:create --no-interaction --username="${!user_name}" \
200
+ --password="${!user_password}" --email="${!user_mail}" --groups="${group}" && echo " ${!user_name} is created." ;
201
+ fi
202
+ fi
203
+ done
204
+ cd ${WORKSPACE_ROOT}/${doc_name};
205
+ }
206
+
207
+ # Delete the default accounts. The console has no command for it, so the records are removed
208
+ # from the project's database, in its container.
209
+ function cancel_typo3_users() {
210
+ typo3_enter_project || return 1 ;
211
+ local user user_name ;
212
+ for user in "${users[@]}" ; do
213
+ user_name="user_${user}_name";
214
+ echo " ---------------------------------------------------------------- ";
215
+ echo " User name: ${!user_name}";
216
+ echo " ================================================================= ";
217
+ if typo3_user_exists "${!user_name}" ; then
218
+ ddev mysql -e "DELETE FROM be_users WHERE username = '${!user_name}'" && echo " ${!user_name} is deleted." ;
219
+ else
220
+ echo " ${!user_name} is not there." ;
221
+ fi
222
+ done
223
+ cd ${WORKSPACE_ROOT}/${doc_name};
224
+ }
225
+
226
+ # What cmd-tools-typo3-cli.sh does: the first of --run, --update, --flush, --add-users,
227
+ # --cancel-users that was asked for; with none of them, what the site is.
228
+ function typo3_cli_tool() {
229
+ trim_project_name ;
230
+ typo3_enter_project || exit 1 ;
231
+
232
+ if ! ddev describe -j 2>/dev/null | grep -q '"status":"running"' ; then
233
+ ddev start -y || exit 1 ;
234
+ fi
235
+
236
+ if [ ! "${RUN}" == '_none_' ] ; then
237
+ # One string on purpose: --run "extension:list --active" is a command and its arguments.
238
+ ddev exec "vendor/bin/typo3 ${RUN}" ;
239
+ exit $? ;
240
+ fi
241
+
242
+ if [ "${UPDATE}" == 'yes' ] ; then
243
+ ddev composer update --with-all-dependencies --no-interaction \
244
+ && typo3_cli extension:setup && typo3_cli cache:flush ;
245
+ elif [ "${FLUSH}" == 'yes' ] ; then
246
+ typo3_cli cache:flush && echo "The caches are flushed." ;
247
+ elif [ "${ADD_USERS}" == 'yes' ] ; then
248
+ set_typo3_users ;
249
+ add_typo3_users ;
250
+ elif [ "${CANCEL_USERS}" == 'yes' ] ; then
251
+ set_typo3_users ;
252
+ cancel_typo3_users ;
253
+ else
254
+ echo "${doc_name}/${PROJECT_NAME}: $(typo3_cli --version 2>/dev/null | head -1) at https://${PROJECT_NAME}.ddev.site" ;
255
+ if typo3_is_installed "$(pwd)" ; then
256
+ echo "" ; echo "Sites:" ; typo3_cli site:list ;
257
+ echo "" ; echo "Backend accounts:" ;
258
+ ddev mysql -t -e "SELECT username, email, IF(admin = 1, 'admin', usergroup) AS role FROM be_users WHERE deleted = 0 AND username <> '_cli_' ORDER BY uid" ;
259
+ else
260
+ echo "The site is not set up yet: open its address at /typo3/install.php, or build it again with --install." ;
261
+ fi
262
+ fi
263
+ cd ${WORKSPACE_ROOT}/${doc_name};
264
+ }
265
+
266
+ # The step pack in the testing stack of a TYPO3 project. The core's testing_configure calls
267
+ # this in the project folder once webship-js is scaffolded and before the dependencies are
268
+ # installed; for a project that is not TYPO3 it changes nothing.
269
+ #
270
+ # It adds the pack to package.json, lists its step definitions in cucumber.js after webship-js's
271
+ # own, gives cucumber.js the users registry of the default accounts (a handle a scenario reads,
272
+ # mapped to an account; never the workspace account), and writes a first feature when the project
273
+ # has none of its own. Every part is skipped when it is already there, so a second run adds what
274
+ # the first missed and never resets a suite.
275
+ function testing_configure_typo3() {
276
+ local project_path="$1";
277
+ typo3_is_project "${project_path}" || return 0 ;
278
+ if [ ! -f "${project_path}/cucumber.js" ] || [ ! -f "${project_path}/package.json" ] ; then
279
+ echo " TYPO3: cucumber.js is not here yet — run the testing setup again once webship-js is scaffolded." ;
280
+ return 1 ;
281
+ fi
282
+
283
+ echo "Adding the TYPO3 step pack (${TYPO3_STEPS_PACKAGE} ${TYPO3_STEPS_VERSION}).";
284
+ set_typo3_users ;
285
+ local registry="" user user_name user_password handle ;
286
+ for user in "${users[@]}" ; do
287
+ user_name="user_${user}_name"; user_password="user_${user}_password";
288
+ # The pack's features call the administrator "admin".
289
+ handle="${user}" ; [ "${user}" == 'administrator' ] && handle="admin" ;
290
+ registry="${registry}${handle}|${!user_name}|${!user_password}"$'\n' ;
291
+ done
292
+
293
+ # The pack reads TYPO3_<HANDLE>_USER and TYPO3_<HANDLE>_PASS: the registry keeps its names.
294
+ python3 - "${project_path}" "${TYPO3_STEPS_PACKAGE}" "${TYPO3_STEPS_VERSION}" 'TYPO3' 'PASS' "${registry}" <<'PYEOF' || return 1
295
+ import json, re, sys
296
+
297
+ project, pack, version, prefix, secret, registry = sys.argv[1:7]
298
+
299
+ # package.json: the pack as a dev dependency, at the release line this plugin was proven on.
300
+ pkg_file = project + '/package.json'
301
+ pkg = json.load(open(pkg_file))
302
+ if pack not in pkg.get('dependencies', {}) and pack not in pkg.get('devDependencies', {}):
303
+ pkg.setdefault('devDependencies', {})[pack] = version
304
+ open(pkg_file, 'w').write(json.dumps(pkg, indent=2) + '\n')
305
+ print(' package.json: %s %s' % (pack, version))
306
+
307
+ # cucumber.js: the pack's step definitions after webship-js's own, and the users registry.
308
+ cucumber_file = project + '/cucumber.js'
309
+ src = open(cucumber_file).read()
310
+ before = src
311
+
312
+ if ('node_modules/%s/' % pack) not in src:
313
+ line = "'node_modules/%s/tests/step-definitions/**/*.js'," % pack
314
+ core = re.search(r"^([ \t]*)'node_modules/webship-js/tests/step-definitions/[^']*',.*$", src, re.M)
315
+ opening = re.search(r"^([ \t]*)require:[ \t]*\[[ \t]*$", src, re.M)
316
+ if core:
317
+ src = src[:core.end()] + '\n' + core.group(1) + line + src[core.end():]
318
+ elif opening:
319
+ src = src[:opening.end()] + '\n' + opening.group(1) + ' ' + line + src[opening.end():]
320
+ else:
321
+ sys.exit(" cucumber.js has no require list this can add to. Add this line to it:\n " + line)
322
+ print(' cucumber.js: the step definitions of %s' % pack)
323
+
324
+ if not re.search(r"^[ \t]*users:[ \t]*\{", src, re.M):
325
+ world = re.search(r"^([ \t]*)worldParameters:[ \t]*\{[ \t]*$", src, re.M)
326
+ if not world:
327
+ sys.exit(" cucumber.js has no worldParameters block to add the users registry to.")
328
+ pad = world.group(1) + ' '
329
+ rows = [r.split('|') for r in registry.splitlines() if r.strip()]
330
+ block = [
331
+ pad + "// The users registry: a handle a scenario reads, mapped to an account of this site (the default",
332
+ pad + "// accounts: cmd-tools-add-users.sh). Override one with %s_<HANDLE>_USER and %s_<HANDLE>_%s." % (prefix, prefix, secret),
333
+ pad + "users: {",
334
+ ]
335
+ for handle, name, password in rows:
336
+ env = '%s_%s' % (prefix, handle.upper())
337
+ block.append(pad + " %s: { username: process.env.%s_USER || '%s', password: process.env.%s_%s || '%s' }," % (handle, env, name, env, secret, password))
338
+ block.append(pad + "},")
339
+ src = src[:world.end()] + '\n' + '\n'.join(block) + src[world.end():]
340
+ print(' cucumber.js: the users registry (%s)' % ', '.join(r[0] for r in rows))
341
+
342
+ if src != before:
343
+ open(cucumber_file, 'w').write(src)
344
+ PYEOF
345
+
346
+ # A first feature, when the project has none for the site yet: the front page, the login form,
347
+ # each default account in its role.
348
+ local feature="${WORKSPACE_SCRIPTS}/plugins/typo3/site.feature" ;
349
+ if [ -f "${feature}" ] && [ ! -f "${project_path}/tests/features/site.feature" ] ; then
350
+ mkdir -p "${project_path}/tests/features" && cp "${feature}" "${project_path}/tests/features/site.feature" \
351
+ && echo " tests/features/site.feature: a first feature for the site" ;
352
+ fi
353
+
354
+ # The scenarios log in as the default accounts: make sure a site that is set up has them.
355
+ if typo3_is_installed "${project_path}" ; then
356
+ ( add_typo3_users > /dev/null ) && echo " the default accounts are on the site (${users[*]})" ;
357
+ fi
358
+ }
@@ -0,0 +1,53 @@
1
+ Feature: The site answers and its accounts work
2
+ As the owner of the site
3
+ I want the front page, the login form and each default account to work
4
+ So that a build that came out broken is caught before anything else is tested
5
+
6
+ # Placed by the workspace's testing setup as a starting point: it is yours to change.
7
+ # The accounts are the default ones (cmd-tools-add-users.sh); a scenario logs in by a handle of
8
+ # the users registry in cucumber.js, so no password is written here. The module names are those
9
+ # of a backend in English.
10
+
11
+ @critical
12
+ Scenario: The front page is served
13
+ Given I am an anonymous user
14
+ And I am on the homepage
15
+ Then the response status code should be 200
16
+ And the page should have a title
17
+
18
+ @critical
19
+ Scenario: The login form is served to a visitor
20
+ Given I am not logged in
21
+ Then I should not be logged in
22
+ And I should see "Username"
23
+ And I should see "Password"
24
+
25
+ Scenario Outline: Each default account logs in
26
+ Given I am a logged in user with the "<handle>" user
27
+ Then I should be logged in as "<handle>"
28
+
29
+ Examples:
30
+ | handle |
31
+ | admin |
32
+ | editor |
33
+
34
+ # The administrator account is an administrator, not a system maintainer: the modules of a
35
+ # system maintainer (Extensions, the Admin Tools) stay with the account that set the site up.
36
+ Scenario: The administrator has the administration modules
37
+ Given I am a logged in user with the "admin" user
38
+ Then I should see the "Page" module
39
+ And I should see the "Backend Users" module
40
+ And I should see the "Log" module
41
+
42
+ Scenario: The editor has the content modules, and no administration module
43
+ Given I am a logged in user with the "editor" user
44
+ Then I should see the "Page" module
45
+ And I should see the "List" module
46
+ And I should not see the "Backend Users" module
47
+ And I should not see the "Log" module
48
+
49
+ Scenario: Logging out ends the session
50
+ Given I am a logged in user with the "editor" user
51
+ When I log out
52
+ Then I should not be logged in
53
+ And I should not see a login error