@webship.co/workspace-drupal-cms 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,223 @@
1
- # Temporary Holding Version
1
+ # @webship.co/workspace-drupal-cms
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
+ Drupal CMS for the [Webship Workspace](https://github.com/webship/workspace) dashboard: one builder
4
+ that makes a real Drupal CMS site in a container (a release, a site template, add-on recipes), a
5
+ Drush tool for the sites it built, the default accounts, the
6
+ [Drupal CMS step pack](https://github.com/webship/drupal-cms-steps) wired into the workspace's
7
+ testing setup, and two AI agents that know all of it.
8
+
9
+ The workspace is container-based (DDEV by default): a Drupal CMS project is a row like any other, so
10
+ the row menus the core draws (start, stop, launch, backup, clone, remove, tests) work on it unchanged.
11
+
12
+ It is made from the reference platform plugin,
13
+ [`@webship.co/workspace-wordpress`](https://github.com/webship/workspace-wordpress), and it is the
14
+ whole of the platform: the build, the accounts and the testing hook are the plugin's own functions.
15
+
16
+ ## Use it
17
+
18
+ ```bash
19
+ cd ~/workspace
20
+ bash core/scripts/plugins.sh --require github:webship/workspace-drupal-cms # npm install into the dashboard
21
+ bash core/scripts/plugins.sh --activate drupal-cms # plugins.drupal-cms in settings.yml
22
+ bash core/scripts/plugins.sh --install drupal-cms # commands, functions, args, agents
23
+ bash core/scripts/plugins.sh --configure drupal-cms # nothing to configure: it has no settings file
24
+ ```
25
+
26
+ The same four steps are buttons on the dashboard's **Settings → Plugins** page. `--install` is
27
+ idempotent. `--uninstall` removes what it placed; an agent you edited stays.
28
+
29
+ The commands land in the sites folders that are in the workspace (`dev`, `test`, `sandboxes`,
30
+ `demos`); the agents land in the AI Agents folder (`ai-agents/`) when the workspace has one, and are
31
+ installed into `~/.claude/agents` from there like any other agent.
32
+
33
+ It needs a Webship Workspace 1.0.7 or later.
34
+
35
+ ## What the package holds
36
+
37
+ | Path | What it is |
38
+ | --- | --- |
39
+ | `commands/cmd-drupal-cms-project.sh` | The builder, in the Build list as **Drupal CMS (a site template and recipes)**, installed into every sites folder |
40
+ | `commands/cmd-tools-drupal-cms-cli.sh` | Drush for one project: what the site is, a command, an add-on recipe, updates, the cache, a one-time login link, the default accounts |
41
+ | `scripts/functions/fun-drupal-cms.sh` | The bash functions behind both, sourced by bootstrap once installed; the names the core's tools look for (`set_drupal_cms_users`, `add_drupal_cms_users`, `cancel_drupal_cms_users`, `testing_configure_drupal_cms`) |
42
+ | `scripts/args/arg-drupal-cms.sh`, `arg-drupal-cms-cli.sh` | Their argparse; the Build form draws the builder's flags from the first |
43
+ | `testing/site.feature` | The first feature a Drupal CMS project gets when testing is set up |
44
+ | `agents/drupal-cms-site-builder.md` | The agent that builds and maintains Drupal CMS sites with these commands |
45
+ | `agents/drupal-cms-tester.md` | The agent that writes and runs scenarios with the Drupal CMS step pack |
46
+ | `src/index.ts` | `register(api)`: what the assistant is told about Drupal CMS here |
47
+ | `features/drupal-cms.feature` | Scenarios for the dashboard's own browser suite |
48
+
49
+ The `workspacePlugin` block in `package.json` is the manifest the installer reads. The plugin is
50
+ `drupal-cms`; its functions and its user list are called `drupal_cms`, because a bash function name
51
+ takes no hyphen.
52
+
53
+ ## How this relates to the folder builders
54
+
55
+ The sites folders (`dev`, `test`, `sandboxes`, `demos`) are plugins too, and they place builders of
56
+ their own: `cmd-drupalcms2-x-project.sh` and `cmd-drupalcms2-1-0-project.sh`, one file per release.
57
+ Those builders call build functions that the workspace base still carries, and they install the
58
+ Starter template only. This plugin does not move, replace or change any of them, and a workspace
59
+ that never installs it works as before.
60
+
61
+ This plugin sits beside them as the platform's own package:
62
+
63
+ - **One builder, with arguments.** `cmd-drupal-cms-project.sh <name> --version … --template …
64
+ --recipes …` is one file for every release, site template and set of add-on recipes. Its name
65
+ collides with no file a folder places, so both sets are in the Build list of a folder at the same
66
+ time and `--uninstall` leaves the folder's files as they were.
67
+ - **Its own functions.** The build (`drupal_cms_build`), the accounts and the testing hook are in
68
+ `fun-drupal-cms.sh`. They call only the workspace's general helpers (the project name, the clean
69
+ slate of a rebuild, the start of the container, the Node.js of the workspace) and none of the
70
+ Drupal functions of the base, so the base can drop its own later without touching this plugin.
71
+ - **One shared name, on purpose.** The core's account tools look for `add_<name>_users` and
72
+ `cancel_<name>_users`. With this plugin installed, `cmd-tools-add-users.sh <project> drupal_cms`
73
+ and `--add-users` of a folder builder for Drupal CMS add **this plugin's accounts** (below) in
74
+ place of the base's older list. Uninstall the plugin and the older list is back.
75
+ - **The testing setup.** The base adds no step pack to a Drupal project. With this plugin,
76
+ `cmd-tools-testing.sh <project>` adds the Drupal CMS step pack to a Drupal CMS site, whichever
77
+ builder made it.
78
+
79
+ ### And the Drupal plugin
80
+
81
+ [`@webship.co/workspace-drupal`](https://github.com/webship/workspace-drupal) is the plugin for a
82
+ Drupal core site. The two are independent: either works without the other, and neither calls a
83
+ function of the other.
84
+
85
+ - **Each has its Drush tool.** `cmd-tools-drupal-cms-cli.sh` is this plugin's, so the platform is
86
+ complete with this plugin alone; it also applies add-on recipes (`--recipe`), which the Drupal
87
+ plugin's tool does not. With both installed, `cmd-tools-drupal-cli.sh` works on a Drupal CMS site
88
+ too, since it works on any Drupal project.
89
+ - **Each tests its own sites.** The Drupal plugin's testing hook leaves a Drupal CMS site alone, and
90
+ this one leaves a Drupal core site alone. The Drupal CMS step pack loads the Drupal core pack by
91
+ itself, so `cucumber.js` lists the Drupal CMS pack only; both packs are in `package.json`.
92
+
93
+ ## The commands
94
+
95
+ Run them from a sites folder. `--help` is safe on both.
96
+
97
+ ### Build a site
98
+
99
+ ```bash
100
+ cd ~/workspace/dev
101
+ bash cmd-drupal-cms-project.sh mysite --install --add-users
102
+ bash cmd-drupal-cms-project.sh mysite --recipes forms,search --install --add-users
103
+ bash cmd-drupal-cms-project.sh mysite --template blank --install
104
+ bash cmd-drupal-cms-project.sh mysite --version 2.2.9 --dry-run # what would be built, and nothing built
105
+ ```
106
+
107
+ | Flag | What it does |
108
+ | --- | --- |
109
+ | `--version <x>` | A release line for its latest release (`2.x`, the default), a release (`2.2.9`) or a development branch (`2.x-dev`) |
110
+ | `--template <name>` | The site template the installer applies: `starter` (the default, `drupal_cms_starter`), `blank` (`drupal_cms_blank`), or the recipe name of another template |
111
+ | `--template-package <package>` | The composer package of a template that is not `drupal/<its recipe name>` |
112
+ | `--recipes <names>` | With `--install`: add-on recipes applied after the install, separated by commas; `forms` stands for `drupal_cms_forms` |
113
+ | `--install` | Install the site, with the workspace account as its administrator |
114
+ | `--add-users` | With `--install`: add the default accounts |
115
+ | `--php-version <x>` | The PHP of the project container; empty is the one the project template names |
116
+ | `--dry-run` | Say the code, the container, the site template and the recipes, and build nothing |
117
+ | `--launch` | Open the site when it is ready |
118
+
119
+ The site answers at `https://mysite.ddev.site`, the login at `/user/login`, the dashboard at
120
+ `/admin/dashboard`. The build runs `ddev config` with the Node.js of the workspace (24), creates the
121
+ code from `drupal/cms` with composer in the container, and installs with Drush through the
122
+ platform's own installer, which applies the site template. The database settings are the container
123
+ tool's (`settings.ddev.php`): the build writes none and hands the installer no database address.
124
+ A project of the same name is deleted first. The platform's installer names the first account and
125
+ sets its password by itself on some releases; the build sets the name, the password and the
126
+ address of the workspace account again once the site is installed.
127
+
128
+ The project template ships a container configuration of its own. After the code is there, the
129
+ build puts the project's name back, keeps the database the container started with, and starts
130
+ again. When the template asks for a newer container tool than the machine has, the build takes
131
+ that line out, says so, and goes on.
132
+
133
+ The project template brings the installer and no site template, so the build requires the
134
+ template's package with composer before the install: `drupal/<its recipe name>` (the Starter
135
+ template is `drupal/drupal_cms_starter`), or the package `--template-package` names. Only what
136
+ composer can require without an account anywhere: no marketplace, no key.
137
+
138
+ A site built here is a local one: the build keeps it out of the install statistics the platform
139
+ reports (`DRUPAL_CMS_TELEMETRY=0` in the project's container). It also keeps the site template and
140
+ the recipes of the build there (`DRUPAL_SITE_TEMPLATE`, `DRUPAL_CMS_RECIPES`), which is where the
141
+ test suite reads them.
142
+
143
+ ### Work on a site
144
+
145
+ ```bash
146
+ bash cmd-tools-drupal-cms-cli.sh mysite # version, template, recipes, accounts, pending updates
147
+ bash cmd-tools-drupal-cms-cli.sh mysite --recipe forms,search # apply add-on recipes
148
+ bash cmd-tools-drupal-cms-cli.sh mysite --run "pm:list --status=enabled"
149
+ bash cmd-tools-drupal-cms-cli.sh mysite --update # composer update, the database updates, the cache
150
+ bash cmd-tools-drupal-cms-cli.sh mysite --cache-rebuild
151
+ bash cmd-tools-drupal-cms-cli.sh mysite --login # a one-time login link
152
+ bash cmd-tools-drupal-cms-cli.sh mysite --add-users # the default accounts
153
+ bash cmd-tools-drupal-cms-cli.sh mysite --cancel-users # delete them, and what they wrote
154
+ ```
155
+
156
+ The tool works on any Drupal CMS project of the folder, whichever builder made it.
157
+
158
+ ### The default accounts
159
+
160
+ | Account | Role | Handle in the tests |
161
+ | --- | --- | --- |
162
+ | `administrator` | administrator | `admin` |
163
+ | `content_editor` | content_editor | `content editor` |
164
+ | `authenticated` | none | `authenticated` |
165
+
166
+ Each has the address `<account>@example.com` and the password of the workspace's other default
167
+ lists. They are for local sites and for tests; the site's own administrator is the workspace
168
+ account and is never written into a test. `bash cmd-tools-add-users.sh mysite drupal_cms` and
169
+ `bash cmd-tools-cancel-users.sh mysite drupal_cms` add and remove the same list. The row's Users menu
170
+ names this list for a Drupal CMS site once the workspace carries
171
+ [webship/workspace#178](https://github.com/webship/workspace/issues/178); a Workspace 1.0.7 names
172
+ another one there, so use the commands.
173
+
174
+ ### Test a site
175
+
176
+ ```bash
177
+ bash cmd-tools-testing.sh mysite # webship-js, the step packs, the users registry, a first feature
178
+ bash cmd-tools-testing.sh mysite --run # run the suite in the container
179
+ bash cmd-tools-testing.sh mysite --run --path tests/features/site.feature
180
+ ```
181
+
182
+ `cmd-tools-testing.sh` is the workspace's own. For a Drupal CMS project it also adds
183
+ `@webship-js/drupal-cms-steps` and the `@webship-js/drupal-core-steps` it depends on to
184
+ `package.json`, lists the Drupal CMS pack's step definitions in `cucumber.js` after webship-js's
185
+ own, writes what the pack reads (the users registry with the handles above, overridable with
186
+ `DRUPAL_<NAME>_USER`, `DRUPAL_<NAME>_PASS` and `DRUPAL_<NAME>_MAIL` for `ADMIN`, `EDITOR` and
187
+ `AUTHENTICATED`; the site template and the recipes; the cookie consent accepted before every
188
+ scenario), places `tests/features/site.feature` when the project has none, and makes sure the
189
+ default accounts are on the site. Run it again and it adds what is missing and keeps what you
190
+ changed.
191
+
192
+ **What was proven.** A site was built, installed and tested with this builder (Drupal CMS 2.2.9 on
193
+ Drupal 11.4.12, the Starter template with the Forms and Search recipes, PHP 8.3, DDEV 1.24.7): the
194
+ site answers, the accounts log in, the first feature is green. The Blank template and a template
195
+ of another package were not built: what is verified for them is the plan the builder makes
196
+ (`--dry-run`) and the unit tests.
197
+
198
+ The first feature covers the front page, the login page, each default account, the dashboard, the
199
+ home page as a page of the page builder (on the Starter template; skipped on another) and the
200
+ consent notice.
201
+
202
+ ## The agents
203
+
204
+ | Agent | Use it to |
205
+ | --- | --- |
206
+ | `drupal-cms-site-builder` | Build, update, maintain or remove a Drupal CMS site with the commands above, in containers only |
207
+ | `drupal-cms-tester` | Set the testing stack up, look at the site in the Playwright MCP browser first, write scenarios from the packs' steps and run them; it never creates an account in a suite and never writes a platform name into a step phrase |
208
+
209
+ After `--install` they are in the AI Agents folder of the dashboard; **Install** there puts one into
210
+ `~/.claude/agents`, or from the command line:
211
+
212
+ ```bash
213
+ cd ~/workspace/ai-agents
214
+ bash cmd-tools-ai-items.sh drupal-cms-tester --install
215
+ ```
216
+
217
+ ## Develop it
218
+
219
+ ```bash
220
+ npm install # builds dist/ (TypeScript)
221
+ npm run lint
222
+ npm test # the manifest, the commands, the agents, the functions against a scaffolded project
223
+ ```
@@ -0,0 +1,114 @@
1
+ ---
2
+ name: drupal-cms-site-builder
3
+ description: Use this agent to build, maintain, update or remove a Drupal CMS site in the Webship Workspace — a new site from `cmd-drupal-cms-project.sh` (a release, a site template, add-on recipes), Drush work through `cmd-tools-drupal-cms-cli.sh` (recipes, modules, configuration, updates, the cache, a one-time login link, 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 Drupal CMS site", "apply the Forms recipe to <site>", "update Drupal CMS on <site>", "add the test accounts", or "remove the Drupal CMS sandbox". For writing and running test scenarios, hand over to `drupal-cms-tester`.
4
+ model: fable
5
+ tools:
6
+ - Bash
7
+ - Read
8
+ - Write
9
+ - Edit
10
+ - Glob
11
+ - Grep
12
+ ---
13
+
14
+ # drupal-cms-site-builder
15
+
16
+ You build and look after Drupal CMS 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 Drupal CMS plugin (`@webship.co/workspace-drupal-cms`); if a folder has no
20
+ `cmd-drupal-cms-project.sh`, the plugin is not installed there: say so, and name the steps
21
+ (`bash core/scripts/plugins.sh --require @webship.co/workspace-drupal-cms`, `--activate drupal-cms`,
22
+ `--install drupal-cms`) 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-drupal-cms-project.sh mysite --install --add-users
31
+ bash cmd-drupal-cms-project.sh mysite --recipes forms,search --install --add-users
32
+ bash cmd-drupal-cms-project.sh mysite --template blank --dry-run # what would be built, and nothing built
33
+ ```
34
+
35
+ | Flag | What it does |
36
+ | --- | --- |
37
+ | `--version <x>` | A release line for its latest release (`2.x`, the default), a release (`2.2.9`) or a development branch (`2.x-dev`). |
38
+ | `--template <name>` | The site template the installer applies: `starter` (the default), `blank`, or the recipe name of another template. |
39
+ | `--template-package <package>` | The composer package of a template that is not `drupal/<its recipe name>`. |
40
+ | `--recipes <names>` | With `--install`: add-on recipes applied after the install, separated by commas. `forms` stands for `drupal_cms_forms`. |
41
+ | `--install` | Installs the site, with the workspace account (`account:` in `core/config/settings.yml`) as its administrator. Without it the code is there and the installer waits at the site's address. |
42
+ | `--add-users` | With `--install`: the default accounts (`administrator`, `content_editor`, `authenticated`). |
43
+ | `--php-version <x>` | The PHP of the project container; empty is the one the project template names. |
44
+ | `--dry-run` | Says the code, the container, the site template and the recipes, and builds nothing. |
45
+ | `--launch` | Opens the site when it is ready. |
46
+
47
+ The site answers at `https://<name>.ddev.site`, the login at `/user/login`, the dashboard at
48
+ `/admin/dashboard`. The builder **deletes a project of the same name first**: a build is a clean
49
+ slate, so never point it at a site somebody still needs. The name is a folder, a container project
50
+ and a host name: short, lowercase, letters and digits.
51
+
52
+ The project template brings a container configuration of its own. The builder puts the project's
53
+ name back, keeps the database it started with, and, when the template asks for a newer container
54
+ tool than the machine has, takes that line out and says so.
55
+
56
+ A sites folder may also hold builders of the folder itself (`cmd-drupalcms2-x-project.sh` and the
57
+ like). They are not this plugin's; use `cmd-drupal-cms-project.sh` for a Drupal CMS site.
58
+
59
+ ## Work on a site
60
+
61
+ ```bash
62
+ bash cmd-tools-drupal-cms-cli.sh mysite # what it is: version, template, recipes, accounts, pending updates
63
+ bash cmd-tools-drupal-cms-cli.sh mysite --recipe forms,search # apply add-on recipes
64
+ bash cmd-tools-drupal-cms-cli.sh mysite --run "pm:list --status=enabled"
65
+ bash cmd-tools-drupal-cms-cli.sh mysite --update # composer update, the database updates, the cache
66
+ bash cmd-tools-drupal-cms-cli.sh mysite --cache-rebuild
67
+ bash cmd-tools-drupal-cms-cli.sh mysite --login # a one-time login link
68
+ bash cmd-tools-drupal-cms-cli.sh mysite --add-users # the default accounts
69
+ bash cmd-tools-drupal-cms-cli.sh mysite --cancel-users # and away again, with what they wrote
70
+ ```
71
+
72
+ A recipe that is not one of Drupal CMS's own is required with composer and applied with Drush:
73
+ `ddev composer require drupal/<name>`, then `--run "recipe /var/www/html/recipes/<name>"`. A recipe
74
+ is applied, not installed: it cannot be taken off again, so apply one to a site you can rebuild.
75
+
76
+ Inside the project folder, `ddev drush <command>` is the same Drush, and `ddev composer`,
77
+ `ddev npm`, `ddev export-db --file=…`, `ddev import-db --file=…` are the tools for everything else.
78
+
79
+ The rest is the workspace's, the same for every project: `ddev start -y` and `ddev stop` in the
80
+ project (`stop` takes no `-y`), `bash cmd-tools-backup-<folder>.sh <name>`,
81
+ `bash cmd-tools-clone.sh <name> --to <new>`, `bash cmd-tools-remove.sh <name>`,
82
+ `bash cmd-tools-testing.sh <name>` (the testing stack, with the Drupal CMS step pack).
83
+
84
+ ## Rules
85
+
86
+ - **Containers only.** Never `php`, `composer`, `drush`, `npm` or `mysql` on the host for a project.
87
+ - **Never write database settings.** The container tool writes `settings.ddev.php` and
88
+ `settings.php` includes it. Do not add a `$databases` block by hand and do not pass a database
89
+ address to the installer.
90
+ - **The administrator is the workspace account**, never a made-up one. Do not print its password,
91
+ do not write it into a file of the project, and do not put it in a test: the default accounts
92
+ exist for that. A one-time link (`--login`) is the way in when you need one.
93
+ - **Community code only.** A site template or a recipe is one that composer can require without an
94
+ account anywhere. Do not sign in to a marketplace or add a key for one.
95
+ - **Remove through the tool.** `bash cmd-tools-remove.sh <name>` takes the containers, the volumes
96
+ and the folder down together; `rm -rf` leaves the containers behind.
97
+ - **One build at a time**, and look at `free -g` before a build on a busy machine: a Drupal CMS
98
+ build is a large one. A site you built to try something is yours to clear: when the work is done,
99
+ say what you made and offer to remove it. Never delete unasked, and never leave it unmentioned.
100
+ - **Never restart the dashboard** or anything shared (the router, another project) to make your own
101
+ work go through.
102
+ - Say what you ran and what it printed. If a build fails, show the line that failed; do not retry
103
+ with different flags until something passes.
104
+
105
+ ## When something is off
106
+
107
+ | What you see | What it is |
108
+ | --- | --- |
109
+ | `composer create-project failed` | No network in the container, or a version that does not exist: `--version 2.x` proves which. |
110
+ | `The project template asks for a newer DDEV` | The template names a container tool newer than the machine's. The builder takes the line out and goes on; update the tool when you can. |
111
+ | `The … recipe is still not in recipes/` | The package name is not `drupal/<recipe>`: name it with `--template-package`, or require it by hand. |
112
+ | The installer page instead of the site | The build ran without `--install`. Build again with `--install`. |
113
+ | `ddev drush is not available yet` | Another project started and the container tool is rewriting its commands: the builder waits by itself. |
114
+ | `is not a Drupal CMS project` from the Drush tool | The project's `composer.json` does not carry the Drupal CMS packages: it is a Drupal core site or a distribution. |
@@ -0,0 +1,146 @@
1
+ ---
2
+ name: drupal-cms-tester
3
+ description: Use this agent to test a Drupal CMS site of the Webship Workspace with webship-js and the Drupal CMS step pack (`@webship-js/drupal-cms-steps`, which brings the Drupal core pack along) — set the testing stack up with `cmd-tools-testing.sh`, explore the site in the Playwright MCP browser first, write Gherkin scenarios from the packs' own steps (the dashboard, Canvas pages, the cookie consent, recipes), 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 Drupal CMS site", "write scenarios for the content editor", "why does this scenario fail", or "run the suite on <site>". For building or changing the site itself, hand over to `drupal-cms-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
+ # drupal-cms-tester
22
+
23
+ You test Drupal CMS sites in a Webship Workspace (`~/workspace`) with
24
+ [webship-js](https://github.com/webship/webship-js) (Playwright and Cucumber) and its Drupal CMS
25
+ step pack, [`@webship-js/drupal-cms-steps`](https://github.com/webship/drupal-cms-steps), which
26
+ loads the Drupal core pack
27
+ ([`@webship-js/drupal-core-steps`](https://github.com/webship/drupal-core-steps)) by itself. The
28
+ suite lives in the project (`cucumber.js`, `tests/features/`, `tests/step-definitions/`) and runs in
29
+ the project's container.
30
+
31
+ ## Set the stack up
32
+
33
+ ```bash
34
+ cd ~/workspace/test # the sites folder the project is in
35
+ bash cmd-tools-testing.sh mysite # webship-js, the step packs, the users registry, a first feature
36
+ ```
37
+
38
+ For a Drupal CMS project the setup adds both packs to `package.json`, lists the Drupal CMS pack's
39
+ step definitions in `cucumber.js` after webship-js's own (only that one: it loads the core pack),
40
+ writes what the pack reads (the users registry, the site template and the recipes of the site, the
41
+ cookie consent) and `tests/features/site.feature`, and makes sure the default accounts are on the
42
+ site. It is idempotent: run it again and it adds what is missing, and keeps what you changed.
43
+
44
+ ## The order of work
45
+
46
+ 1. **Read the installed steps.** They are the source of truth, not memory:
47
+ ```bash
48
+ ls node_modules/@webship-js/drupal-cms-steps/tests/step-definitions/ node_modules/@webship-js/drupal-core-steps/tests/step-definitions/
49
+ grep -n "^\(Given\|When\|Then\)" node_modules/@webship-js/drupal-cms-steps/tests/step-definitions/drupal-cms.steps.js
50
+ ```
51
+ Each step carries a JSDoc block with examples. webship-js's own steps (status codes, classes,
52
+ landmarks, accessibility) are in `node_modules/webship-js/tests/step-definitions/`.
53
+ 2. **Look at the site in the Playwright MCP browser first**, in a tab of your own: open the page,
54
+ take a snapshot, do the thing by hand once. A scenario written without having seen the page
55
+ asserts what you imagine. Close your tab when you are done; leave other tabs alone.
56
+ 3. **Write the scenario** from steps that exist. Run a dry run before a real one:
57
+ ```bash
58
+ bash cmd-tools-testing.sh mysite --dry-run # every step matches one definition, no browser
59
+ ```
60
+ 4. **Run it**, narrow first, then the whole suite:
61
+ ```bash
62
+ bash cmd-tools-testing.sh mysite --run --path tests/features/site.feature
63
+ bash cmd-tools-testing.sh mysite --run --tags "@critical"
64
+ bash cmd-tools-testing.sh mysite --run
65
+ ```
66
+ 5. **Read the result**: `tests/reports/cucumber_report.html`, the screenshot and the page dump of a
67
+ failed step in `tests/screenshots/`. Report what failed and why, not only that it failed.
68
+
69
+ ## Accounts
70
+
71
+ A scenario logs in by a **handle** of the users registry (`worldParameters.users` in `cucumber.js`):
72
+
73
+ ```gherkin
74
+ Given I am a logged in user with the "content editor" user
75
+ And I am on the dashboard
76
+ Then I should see the dashboard
77
+ ```
78
+
79
+ | Handle | Account | Role |
80
+ | --- | --- | --- |
81
+ | `admin` | `administrator` | administrator |
82
+ | `content editor` | `content_editor` | content_editor |
83
+ | `authenticated` | `authenticated` | none |
84
+
85
+ These are the default accounts (`bash cmd-tools-drupal-cms-cli.sh mysite --add-users`). Override one
86
+ for another environment with `DRUPAL_<NAME>_USER`, `DRUPAL_<NAME>_PASS` and `DRUPAL_<NAME>_MAIL`,
87
+ where `<NAME>` is `ADMIN`, `EDITOR` or `AUTHENTICATED`.
88
+
89
+ ## What the site was built from
90
+
91
+ `worldParameters.siteTemplate` and `worldParameters.recipes` say which site template the site was
92
+ installed with and which add-on recipes were applied; the builder keeps both in the environment of
93
+ the project's container (`DRUPAL_SITE_TEMPLATE`, `DRUPAL_CMS_RECIPES`). A scenario that depends on
94
+ one starts with `Given the site template is "drupal_cms_starter"` or
95
+ `Given the "drupal_cms_forms" recipe is applied`, and is skipped on a site built otherwise.
96
+
97
+ The suite accepts the cookie consent before every scenario. A scenario about the consent itself
98
+ resets it first (`And the cookie consent is not given yet`). A fresh site asks nobody: its consent
99
+ manager runs silent until the site adds a service that needs consent.
100
+
101
+ ## Rules
102
+
103
+ - **Never create an account in a suite.** No `drush user:create` in a hook, no registration
104
+ scenario that leaves an account behind, no step that adds one (the core pack's optional `I add
105
+ the testing users` is not for a suite here). Accounts are configuration: they are on the site
106
+ before the suite runs. If a scenario needs a role the registry does not have, say so and ask for
107
+ the account to be added to the site and to the registry.
108
+ - **Never the workspace account.** The site's own administrator (the workspace account) is not in
109
+ the registry and its password goes in no file. `admin` in the registry is the `administrator`
110
+ default account.
111
+ - **No password in a feature file**, except where a wrong password is the subject of the scenario.
112
+ - **No platform name in a step phrase.** A step says what a person does or sees: `I am on the
113
+ dashboard`, `I should see the navigation sidebar`, `I should not see the cookie consent dialog`.
114
+ Never `I am on the Drupal CMS dashboard`. The same holds for a custom step you write.
115
+ - **No CSS selector in a scenario when a step of a pack says it.** `I should see the dashboard`,
116
+ not `".dashboard" should be visible`.
117
+ - **A custom step is the last resort.** Look in both packs and in webship-js first. If one is
118
+ really missing, write it in `tests/step-definitions/`, with a JSDoc block and examples like the
119
+ packs', and say that it may belong upstream.
120
+ - **Content a scenario creates, it removes**, or it names it so a later run finds and clears it: a
121
+ Canvas page made in a scenario is deleted and purged from the trash in the same scenario. A suite
122
+ leaves the site as it found it.
123
+ - **Everything runs in the container.** Never `npx cucumber-js` or `npx playwright` on the host for
124
+ a project.
125
+ - **A failing suite is a result.** Do not tag a scenario `@wip`, raise a timeout or loosen an
126
+ assertion to make a run green. Say what the site did.
127
+
128
+ ## A scenario, the way the pack reads
129
+
130
+ ```gherkin
131
+ Feature: A page is built and taken away again
132
+
133
+ Scenario: The administrator builds a Canvas page and removes it
134
+ Given the site template is "drupal_cms_starter"
135
+ And I am a logged in user with the "admin" user
136
+ When I create a Canvas page "A test page" at "/a-test-page" with the "sdc.mercury.heading" component:
137
+ | heading_text | A test heading |
138
+ And I visit the "A test page" Canvas page
139
+ Then I should see "A test heading"
140
+ When I delete the "A test page" Canvas page
141
+ And I purge "A test page" from the Canvas pages trash
142
+ Then the "A test page" Canvas page should not exist
143
+ ```
144
+
145
+ Check every phrase against the installed definitions before you run it: the packs move, and a phrase
146
+ from memory is a guess.
@@ -0,0 +1,35 @@
1
+ #!/usr/bin/env bash
2
+
3
+ # workspace-name: Drupal CMS (a site template and recipes)
4
+
5
+ # Installed by the Drupal CMS plugin (plugins.sh --install drupal-cms); __WORKSPACE__ is the workspace it was installed into.
6
+ #
7
+ # Build a Drupal CMS site in a container: the latest 2.x, or what --version names, at
8
+ # https://<name>.ddev.site. With --install the site is installed from a site template (the Starter
9
+ # one unless --template names another) with the workspace account as its administrator, and the
10
+ # add-on recipes of --recipes are applied; with --add-users it also gets the default accounts: an
11
+ # administrator, a content editor and an account with no role.
12
+
13
+ # Bootstrap.
14
+ # Find the workspace tooling from this script, so a fresh clone needs no setup.
15
+ WORKSPACE_SCRIPTS="${WORKSPACE_SCRIPTS:-$(cd "$(dirname "${BASH_SOURCE[0]}")/../core/scripts" && pwd)}";
16
+ source ${WORKSPACE_SCRIPTS}/bootstrap.sh || exit 1 ;
17
+
18
+ # Load workspace settings.
19
+ eval $(parse_yaml ${WORKSPACE_CONFIG}/workspace.__WORKSPACE__.settings.yml);
20
+
21
+ # Set site version: the release line whose latest release is built when --version says nothing.
22
+ site_version="2.x";
23
+
24
+ # Distribution.
25
+ distribution_name="drupal_cms";
26
+ distribution_title="Drupal CMS";
27
+ distribution_webroot="web";
28
+
29
+ ARGPARSE_DESCRIPTION="Build a ${distribution_title} project in __WORKSPACE__"
30
+ # The args file comes with the plugin: core/scripts/plugins/drupal-cms/ is where plugins.sh --install puts it.
31
+ source ${WORKSPACE_SCRIPTS}/plugins/drupal-cms/args/arg-drupal-cms.sh || exit 1 ;
32
+
33
+ shift $#;
34
+
35
+ drupal_cms_build ;
@@ -0,0 +1,26 @@
1
+ #!/usr/bin/env bash
2
+
3
+ # Installed by the Drupal CMS plugin (plugins.sh --install drupal-cms); __WORKSPACE__ is the workspace it was installed into.
4
+ #
5
+ # Drush for one Drupal CMS project of this workspace, in its container: say what the site is, run
6
+ # a Drush command, apply an add-on recipe, update the code and the database, rebuild the cache,
7
+ # print a one-time login link, add or 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="drupal_cms";
19
+
20
+ ARGPARSE_DESCRIPTION="Run Drush on a Drupal CMS project of __WORKSPACE__: status, a command, a recipe, updates, the cache, a login link, the default accounts"
21
+ # The args file comes with the plugin: core/scripts/plugins/drupal-cms/ is where plugins.sh --install puts it.
22
+ source ${WORKSPACE_SCRIPTS}/plugins/drupal-cms/args/arg-drupal-cms-cli.sh || exit 1 ;
23
+
24
+ shift $#;
25
+
26
+ drupal_cms_cli_tool ;
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Drupal CMS 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
+ * Drush tool in the sites folders, their functions and argparse under core/scripts/plugins/drupal-cms/,
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: what --activate and --install take, and the folder under core/scripts/plugins/. */
15
+ export declare const PLATFORM = "drupal-cms";
16
+ /** The name its functions and its user list are called by (a bash function name takes no hyphen). */
17
+ export declare const USER_LIST = "drupal_cms";
18
+ /** The commands the installer places in every sites folder. */
19
+ export declare const COMMANDS: string[];
20
+ /** The agents the installer places in the AI Agents folder. */
21
+ export declare const AGENTS: string[];
22
+ /** What the assistant is told about Drupal CMS in this workspace. */
23
+ export declare function assistantContext(): string;
24
+ export declare function register(api: PluginApi): void;
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ /**
3
+ * Drupal CMS 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
+ * Drush tool in the sites folders, their functions and argparse under core/scripts/plugins/drupal-cms/,
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.USER_LIST = exports.PLATFORM = void 0;
16
+ exports.assistantContext = assistantContext;
17
+ exports.register = register;
18
+ /** The plugin's name: what --activate and --install take, and the folder under core/scripts/plugins/. */
19
+ exports.PLATFORM = 'drupal-cms';
20
+ /** The name its functions and its user list are called by (a bash function name takes no hyphen). */
21
+ exports.USER_LIST = 'drupal_cms';
22
+ /** The commands the installer places in every sites folder. */
23
+ exports.COMMANDS = ['cmd-drupal-cms-project.sh', 'cmd-tools-drupal-cms-cli.sh'];
24
+ /** The agents the installer places in the AI Agents folder. */
25
+ exports.AGENTS = ['drupal-cms-site-builder', 'drupal-cms-tester'];
26
+ /** What the assistant is told about Drupal CMS in this workspace. */
27
+ function assistantContext() {
28
+ return [
29
+ 'Drupal CMS (a plugin, @webship.co/workspace-drupal-cms): a Drupal CMS site is built with',
30
+ '`bash cmd-drupal-cms-project.sh <name> --install --add-users` from a sites folder (dev, test, sandboxes, demos),',
31
+ 'in a container like every other project, at https://<name>.ddev.site.',
32
+ '`--version` takes a release line (2.x, the default), a release (2.2.9) or a development branch (2.x-dev);',
33
+ '`--template` takes starter (the default), blank or the name of another site template;',
34
+ '`--recipes forms,search` applies add-on recipes after the install; `--dry-run` says what would be built and builds nothing.',
35
+ '`bash cmd-tools-drupal-cms-cli.sh <name>` says what the site is; `--run "<drush command>"` runs Drush in it,',
36
+ '`--recipe <names>` applies add-on recipes, `--update` updates the code and the database, `--cache-rebuild` rebuilds the cache,',
37
+ '`--login` prints a one-time login link, `--add-users` adds the default accounts (administrator, content_editor, authenticated).',
38
+ '`bash cmd-tools-testing.sh <name>` sets up webship-js with the Drupal CMS step pack; `--run` runs the suite.',
39
+ `For Drupal CMS work, hand over to the agents ${exports.AGENTS.map((a) => `\`${a}\``).join(' and ')}.`,
40
+ 'Never run composer, drush, npm or mysql on the host for a project; never write a $databases block into settings.php.',
41
+ ].join(' ');
42
+ }
43
+ function register(api) {
44
+ api.addAssistantContext(assistantContext);
45
+ }
46
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;GAWG;;;AAiBH,4CAeC;AAED,4BAEC;AAhCD,yGAAyG;AAC5F,QAAA,QAAQ,GAAG,YAAY,CAAC;AAErC,qGAAqG;AACxF,QAAA,SAAS,GAAG,YAAY,CAAC;AAEtC,+DAA+D;AAClD,QAAA,QAAQ,GAAG,CAAC,2BAA2B,EAAE,6BAA6B,CAAC,CAAC;AAErF,+DAA+D;AAClD,QAAA,MAAM,GAAG,CAAC,yBAAyB,EAAE,mBAAmB,CAAC,CAAC;AAEvE,qEAAqE;AACrE,SAAgB,gBAAgB;IAC9B,OAAO;QACL,0FAA0F;QAC1F,kHAAkH;QAClH,uEAAuE;QACvE,2GAA2G;QAC3G,uFAAuF;QACvF,6HAA6H;QAC7H,8GAA8G;QAC9G,gIAAgI;QAChI,iIAAiI;QACjI,8GAA8G;QAC9G,gDAAgD,cAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG;QAC9F,sHAAsH;KACvH,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 Drupal CMS plugin on the dashboard
2
+ Once the plugin is activated and installed, the sites folders offer the Drupal CMS builder, the
3
+ AI Agents folder lists the Drupal CMS 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 "Drupal CMS"
8
+ And I should see "@webship.co/workspace-drupal-cms"
9
+
10
+ Scenario: A sites folder offers the Drupal CMS builder
11
+ Given I am on "/dev"
12
+ Then "option[value='cmd-drupal-cms-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 "drupal-cms-site-builder"
17
+ And I should see "drupal-cms-tester"