@webship.co/workspace-odoo 1.0.7 → 1.0.9
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 +66 -18
- package/{agents → ai/agents}/odoo-site-builder.md +8 -0
- package/{agents → ai/agents}/odoo-tester.md +12 -2
- package/ai/commands/odoo-test.md +88 -0
- package/ai/prompts/odoo-build-and-test.md +27 -0
- package/ai/skills/odoo-scenarios/SKILL.md +236 -0
- package/ai/skills/odoo-scenarios/examples/apps-and-views.feature +36 -0
- package/ai/skills/odoo-scenarios/examples/contact-lifecycle.feature +29 -0
- package/ai/skills/odoo-scenarios/examples/website.feature +43 -0
- package/dist/src/index.d.ts +8 -2
- package/dist/src/index.js +11 -3
- package/dist/src/index.js.map +1 -1
- package/docs/plugin-items-pattern.md +145 -0
- package/features/odoo.feature +15 -2
- package/package.json +27 -5
- package/scripts/functions/fun-odoo.sh +1 -1
package/README.md
CHANGED
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
Odoo Community for the [Webship Workspace](https://github.com/webship/workspace) dashboard: a
|
|
4
4
|
builder that makes a real Odoo site in containers, an odoo-bin tool for the sites it built, the
|
|
5
5
|
default accounts, the [Odoo step pack](https://github.com/webship/odoo-steps) wired into the
|
|
6
|
-
workspace's testing setup, and
|
|
6
|
+
workspace's testing setup, and its AI items — two agents, a skill, a
|
|
7
|
+
command and a prompt — each listed in the workspace folder of its kind.
|
|
7
8
|
|
|
8
9
|
The workspace is container-based (DDEV by default): an Odoo project is a row like any other, so
|
|
9
10
|
the row menus the core draws (start, stop, launch, backup, clone, remove, tests) work on it
|
|
@@ -23,20 +24,47 @@ what Odoo needs, see [What is different from a PHP platform](#what-is-different-
|
|
|
23
24
|
cd ~/workspace
|
|
24
25
|
bash core/scripts/plugins.sh --require github:webship/workspace-odoo # npm install into the dashboard
|
|
25
26
|
bash core/scripts/plugins.sh --activate odoo # plugins.odoo in settings.yml
|
|
26
|
-
bash core/scripts/plugins.sh --install odoo # commands, functions, args,
|
|
27
|
+
bash core/scripts/plugins.sh --install odoo # commands, functions, args, AI items
|
|
27
28
|
bash core/scripts/plugins.sh --configure odoo # nothing to configure: it has no settings file
|
|
28
29
|
```
|
|
29
30
|
|
|
30
31
|
The same four steps are buttons on the dashboard's **Settings → Plugins** page. `--install` is
|
|
31
|
-
idempotent. `--uninstall` removes what it placed; an
|
|
32
|
+
idempotent. `--uninstall` removes what it placed; an AI item you edited stays.
|
|
32
33
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
34
|
+
Everything the plugin carries lands in the folder it belongs to, when that folder is an active
|
|
35
|
+
workspace folder:
|
|
36
|
+
|
|
37
|
+
| What | Lands in |
|
|
38
|
+
| --- | --- |
|
|
39
|
+
| `cmd-odoo-project.sh`, `cmd-tools-odoo-cli.sh` | every active sites folder: `dev/`, `test/`, `sandboxes/`, `demos/` |
|
|
40
|
+
| The agents `odoo-site-builder`, `odoo-tester` | `ai-agents/` |
|
|
41
|
+
| The skill `odoo-scenarios` | `ai-skills/` |
|
|
42
|
+
| The command `/odoo-test` | `ai-commands/` |
|
|
43
|
+
| The prompt `odoo-build-and-test` | `ai-prompts/` |
|
|
44
|
+
|
|
45
|
+
There they are listed like any other item of the folder, and installed into Claude Code from there.
|
|
36
46
|
|
|
37
47
|
The agents, the builder's flags in the Build form and the step pack in the testing setup need a
|
|
38
48
|
Webship Workspace after 1.0.6.
|
|
39
49
|
|
|
50
|
+
## What it needs
|
|
51
|
+
|
|
52
|
+
A workspace starts empty, so the manifest says what else this plugin needs (`needs`):
|
|
53
|
+
|
|
54
|
+
- one sites folder, for the builder and the tool: `dev`, `test`, `sandboxes`, `demos` (`dev` is the one added when none is there). The folder also carries `cmd-tools-testing.sh` and the Users tools this plugin's hooks answer to.
|
|
55
|
+
- `ai-agents`, `ai-skills`, `ai-commands` and `ai-prompts`: the AI folders its agents, its skill, its command and its prompt are placed in.
|
|
56
|
+
|
|
57
|
+
`--require` says so, `--activate` and `--install` stop until the workspace has them, and `--with-needs` adds what is missing first:
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
bash core/scripts/plugins.sh --activate odoo --with-needs # dev and the four AI folders are required, activated and installed first
|
|
61
|
+
bash core/scripts/plugins.sh --install odoo
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Everything the builder runs for a site runs in the site's own container, through the container tool the workspace already needs; the plugin asks for no command of its own on the machine.
|
|
65
|
+
|
|
66
|
+
A workspace that knows none of this (Webship Workspace 1.0.8 and older) ignores the keys: add a sites folder and the AI folders yourself, then `--install odoo` again. A kind whose folder is not there is skipped, and the install says so.
|
|
67
|
+
|
|
40
68
|
## This builder and `cmd-odoo20-project.sh`
|
|
41
69
|
|
|
42
70
|
The sites folders of the workspace (the `dev`, `test` and `sandboxes` folder plugins) carry an
|
|
@@ -71,10 +99,14 @@ and its testing setup work on the projects `cmd-odoo-project.sh` built (they car
|
|
|
71
99
|
| `scripts/args/arg-odoo.sh`, `arg-odoo-cli.sh` | Their argparse; the Build form draws the builder's flags from the first |
|
|
72
100
|
| `scripts/odoo-accounts.py` | The administrator, the default accounts and what keeps the site local, run in the Odoo shell of the project |
|
|
73
101
|
| `testing/site.feature` | The first feature an Odoo project gets when testing is set up |
|
|
74
|
-
| `agents/odoo-site-builder.md` | The agent that builds and maintains Odoo sites with these commands |
|
|
75
|
-
| `agents/odoo-tester.md` | The agent that writes and runs scenarios with the Odoo step pack |
|
|
102
|
+
| `ai/agents/odoo-site-builder.md` | The agent that builds and maintains Odoo sites with these commands |
|
|
103
|
+
| `ai/agents/odoo-tester.md` | The agent that writes and runs scenarios with the Odoo step pack |
|
|
104
|
+
| `ai/skills/odoo-scenarios/` | The skill: the step pack's phrases by area, the traps found on a real site, three example features |
|
|
105
|
+
| `ai/commands/odoo-test.md` | The slash command `/odoo-test <site>`: set up, match every step, run, report |
|
|
106
|
+
| `ai/prompts/odoo-build-and-test.md` | A prompt: the whole launch command for a new session |
|
|
76
107
|
| `src/index.ts` | `register(api)`: what the assistant is told about Odoo here |
|
|
77
108
|
| `features/odoo.feature` | Scenarios for the dashboard's own browser suite |
|
|
109
|
+
| `docs/plugin-items-pattern.md` | How a plugin carries its own commands and AI items, and how to prove it |
|
|
78
110
|
|
|
79
111
|
The `workspacePlugin` block in `package.json` is the manifest the installer reads.
|
|
80
112
|
|
|
@@ -163,25 +195,41 @@ webship-js's own, writes the users registry (the handles above, overridable with
|
|
|
163
195
|
project has none, and makes sure the default accounts are on the site. Run it again and it adds
|
|
164
196
|
what is missing and keeps what you changed.
|
|
165
197
|
|
|
166
|
-
## The
|
|
198
|
+
## The AI items
|
|
167
199
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
| `odoo-site-builder` | Build, update, restart, maintain or remove an Odoo Community site with the commands above, in containers only |
|
|
171
|
-
| `odoo-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 |
|
|
200
|
+
`ai/` in the package holds one folder per kind, the manifest's `ai` block names each item, and
|
|
201
|
+
`--install` places it in the workspace folder of that kind.
|
|
172
202
|
|
|
173
|
-
|
|
174
|
-
|
|
203
|
+
| Kind | Item | Use it to |
|
|
204
|
+
| --- | --- | --- |
|
|
205
|
+
| Agent | `odoo-site-builder` | Build, update, restart, maintain or remove an Odoo Community site with the commands above, in containers only |
|
|
206
|
+
| Agent | `odoo-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 |
|
|
207
|
+
| Skill | `odoo-scenarios` | Write a scenario from phrases that exist: the pack's steps by area (sessions, apps and menus, views and search, records and the chatter, the website), the handles of the users registry, the traps found on a real site, and three features that pass on a fresh site with the default apps and demo data |
|
|
208
|
+
| Command | `/odoo-test <site> [feature or @tag]` | Run the suite of a site from inside a session: set up when missing, match every step, run, report what failed and why |
|
|
209
|
+
| Prompt | `odoo-build-and-test` | Start a session that builds a Community site, says what it is, sets the testing stack up and runs the first feature |
|
|
210
|
+
|
|
211
|
+
After `--install` each is in its folder on the dashboard. **Install** there puts an agent, a skill
|
|
212
|
+
or a command into Claude Code (`~/.claude/agents`, `~/.claude/skills`, `~/.claude/commands`), or
|
|
213
|
+
from the command line:
|
|
175
214
|
|
|
176
215
|
```bash
|
|
177
|
-
cd ~/workspace/ai-agents
|
|
178
|
-
bash cmd-tools-ai-items.sh odoo-
|
|
216
|
+
cd ~/workspace/ai-agents && bash cmd-tools-ai-items.sh odoo-tester --install
|
|
217
|
+
cd ~/workspace/ai-skills && bash cmd-tools-ai-items.sh odoo-scenarios --install
|
|
218
|
+
cd ~/workspace/ai-commands && bash cmd-tools-ai-items.sh odoo-test --install
|
|
179
219
|
```
|
|
180
220
|
|
|
221
|
+
A prompt is not installed: it is the whole `claude …` launch command of a new session, and the
|
|
222
|
+
dashboard's **New screen** form lists it as a template. By hand, fill the placeholders in and run
|
|
223
|
+
the command of the file from the folder it names.
|
|
224
|
+
|
|
225
|
+
Every step phrase the items show is checked against the definitions of the step pack and of
|
|
226
|
+
webship-js (`tests/fixtures/step-definitions.txt`), and every command and flag against the
|
|
227
|
+
plugin's own.
|
|
228
|
+
|
|
181
229
|
## Develop it
|
|
182
230
|
|
|
183
231
|
```bash
|
|
184
232
|
npm install # builds dist/ (TypeScript)
|
|
185
233
|
npm run lint
|
|
186
|
-
npm test # the manifest, the commands, the
|
|
234
|
+
npm test # the manifest, the commands, the AI items, the functions against a scaffolded project
|
|
187
235
|
```
|
|
@@ -129,3 +129,11 @@ other; the files Odoo stores (attachments) are in the `odoo_data` volume of the
|
|
|
129
129
|
| The database selector, or "database does not exist" | The build ran without `--install`: `--install-apps contacts` creates the database, or build again with `--install`. |
|
|
130
130
|
| `… is archived instead of deleted` from `--cancel-users` | The account is part of the data of the site (the demo data has a `portal` user), or records point at it; `--add-users` activates it again. |
|
|
131
131
|
| `is not an Odoo project of this plugin` from the CLI tool | The project has no `.ddev/config.odoo.yaml`: it was built by the folder's example builder, or by hand. |
|
|
132
|
+
|
|
133
|
+
## What comes with you
|
|
134
|
+
|
|
135
|
+
The Odoo plugin places these beside you, each in the workspace folder of its kind: the agent
|
|
136
|
+
`odoo-tester` (`ai-agents/`), the skill `odoo-scenarios` (`ai-skills/`), the command
|
|
137
|
+
`/odoo-test <site>` (`ai-commands/`) and the prompt `odoo-build-and-test` (`ai-prompts/`), which
|
|
138
|
+
is this agent's whole first job as a launch command: build, say what the site is, set the testing
|
|
139
|
+
stack up, run the first feature.
|
|
@@ -20,8 +20,8 @@ tools:
|
|
|
20
20
|
|
|
21
21
|
# odoo-tester
|
|
22
22
|
|
|
23
|
-
You test Odoo Community sites in a Webship Workspace (`~/workspace`)
|
|
24
|
-
[webship-js](https://github.com/webship/webship-js) (Playwright and Cucumber) and its Odoo step
|
|
23
|
+
You test Odoo Community sites in a Webship Workspace (`~/workspace`), a container-based
|
|
24
|
+
workspace (DDEV by default), with [webship-js](https://github.com/webship/webship-js) (Playwright and Cucumber) and its Odoo step
|
|
25
25
|
pack, [`@webship-js/odoo-steps`](https://github.com/webship/odoo-steps). The suite lives in the
|
|
26
26
|
project (`cucumber.js`, `tests/features/`, `tests/step-definitions/`) and runs in the project's web
|
|
27
27
|
container, against the project's address.
|
|
@@ -133,3 +133,13 @@ Feature: A salesperson works on quotations, not on invoices
|
|
|
133
133
|
|
|
134
134
|
Check every phrase against the installed definitions before you run it: the pack moves, and a phrase
|
|
135
135
|
from memory is a guess.
|
|
136
|
+
|
|
137
|
+
## What comes with you
|
|
138
|
+
|
|
139
|
+
The Odoo plugin places these beside you, each in the workspace folder of its kind:
|
|
140
|
+
|
|
141
|
+
| Item | Where | What it is for |
|
|
142
|
+
| --- | --- | --- |
|
|
143
|
+
| `odoo-scenarios` (skill) | `ai-skills/` | The pack's phrases by area, the traps found on a real site, and three example features that pass on a fresh site |
|
|
144
|
+
| `/odoo-test <site>` (command) | `ai-commands/` | The run itself: set up when missing, match every step, run, report |
|
|
145
|
+
| `odoo-build-and-test` (prompt) | `ai-prompts/` | A new session that builds a site with `odoo-site-builder`'s commands and runs its first feature |
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Test a Odoo Community site of the Webship Workspace with webship-js and the Odoo step pack — set the testing stack up when it is missing, match every step, run the suite (or one feature, or one tag) in the site's container, and report what failed and why.
|
|
3
|
+
argument-hint: '<site> [tests/features/<name>.feature | @tag]'
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# /odoo-test
|
|
7
|
+
|
|
8
|
+
Test the Odoo Community site named in: `$ARGUMENTS`
|
|
9
|
+
|
|
10
|
+
The first word is the site (its folder name in a sites folder of the workspace). What follows, if
|
|
11
|
+
anything, narrows the run: a path that starts with `tests/features/` is one feature (or one
|
|
12
|
+
folder of features), a word that starts with `@` is a tag expression. With nothing after the site,
|
|
13
|
+
the whole suite runs. With no site at all, stop and ask for one: list the candidates with
|
|
14
|
+
`ls -d ~/workspace/*/*/.ddev/config.odoo.yaml`.
|
|
15
|
+
|
|
16
|
+
The workspace is container-based (DDEV by default) and everything below runs in the site's
|
|
17
|
+
container through the workspace's own command. Never run `npx cucumber-js`, `npx playwright`,
|
|
18
|
+
`odoo-bin`, `python`, `psql` or `npm` on the host for a site.
|
|
19
|
+
|
|
20
|
+
## 1. Find the site
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
ls ~/workspace/*/<site>/.ddev/config.odoo.yaml
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
`<folder>` is the sites folder the site is in (`dev`, `test`, `sandboxes`, `demos`). If the file is
|
|
27
|
+
not there, stop: this command is for a site built with `cmd-odoo-project.sh`, which writes it. If
|
|
28
|
+
`<folder>` has no `cmd-tools-testing.sh`, stop and say that the folder is not a sites folder of
|
|
29
|
+
this workspace.
|
|
30
|
+
|
|
31
|
+
## 2. Make sure the site answers and the testing stack is there
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
cd ~/workspace/<folder>
|
|
35
|
+
bash cmd-tools-odoo-cli.sh <site>
|
|
36
|
+
grep -c "@webship-js/odoo-steps" <site>/cucumber.js
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
The first prints the version, the address, the apps and the accounts; if the site does not answer,
|
|
40
|
+
`bash cmd-tools-odoo-cli.sh <site> --restart` starts it again and waits for it. If `cucumber.js`
|
|
41
|
+
is missing or does not name the step pack, set the stack up (it adds what is missing and keeps
|
|
42
|
+
what was changed):
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
bash cmd-tools-testing.sh <site>
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## 3. Match every step, without a browser
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
bash cmd-tools-testing.sh <site> --dry-run # the whole suite
|
|
52
|
+
bash cmd-tools-testing.sh <site> --dry-run --path tests/features/<name>.feature # one feature
|
|
53
|
+
bash cmd-tools-testing.sh <site> --dry-run --tags "@critical" # one tag
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Use the form that matches what was asked. An `Undefined` or `Ambiguous` step is a finding: name
|
|
57
|
+
the feature, the line and the phrase, show the closest phrase the pack defines
|
|
58
|
+
(`grep -hE "^(Given|When|Then)\(" <site>/node_modules/@webship-js/odoo-steps/tests/step-definitions/*.steps.js`),
|
|
59
|
+
and stop before the real run.
|
|
60
|
+
|
|
61
|
+
## 4. Run
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
bash cmd-tools-testing.sh <site> --run # the whole suite
|
|
65
|
+
bash cmd-tools-testing.sh <site> --run --path tests/features/<name>.feature # one feature
|
|
66
|
+
bash cmd-tools-testing.sh <site> --run --tags "@critical" # one tag
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Run it once. Do not add `--retry`, do not tag a scenario `@wip` and do not change a feature to
|
|
70
|
+
make the run pass.
|
|
71
|
+
|
|
72
|
+
## 5. Report
|
|
73
|
+
|
|
74
|
+
Say, in this order:
|
|
75
|
+
|
|
76
|
+
1. The site, its address (`https://<site>.ddev.site`) and what was run (suite, feature or tag).
|
|
77
|
+
2. The totals the run printed: scenarios and steps, passed and failed, and the time.
|
|
78
|
+
3. For each failed scenario: the feature and line, the step that failed, the message, and what
|
|
79
|
+
it means for the site — a defect of the site, a scenario that asserts something the site never
|
|
80
|
+
did, or the environment (the site was stopped, an account is missing:
|
|
81
|
+
`bash cmd-tools-odoo-cli.sh <site> --add-users` adds the default ones).
|
|
82
|
+
4. Where the report is: `~/workspace/<folder>/<site>/tests/reports/`.
|
|
83
|
+
|
|
84
|
+
A failing suite is a result: report it as it is. The site is the Community edition: a scenario
|
|
85
|
+
that needs an app of another edition is reported as such, never worked around. Never create an account for a scenario,
|
|
86
|
+
never write a password into a feature file, and never write a platform name into a step phrase.
|
|
87
|
+
For writing or fixing scenarios, use the `odoo-scenarios` skill or hand over to the `odoo-tester`
|
|
88
|
+
agent; for changing the site, to `odoo-site-builder`.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
Build an Odoo Community site in a sites folder and prove it with its first webship-js feature.
|
|
2
|
+
|
|
3
|
+
`claude` is the default launcher; the text between the triple quotes is plain and can be given to another AI CLI as it is.
|
|
4
|
+
|
|
5
|
+
```
|
|
6
|
+
claude --permission-mode bypassPermissions """
|
|
7
|
+
Build an Odoo Community site named <name> in this sites folder and test it with webship-js
|
|
8
|
+
# ~/workspace/<dev|test|sandboxes|demos> · https://<name>.ddev.site · the login at /web/login · container-based (DDEV by default)
|
|
9
|
+
# the builder deletes a project of the same name first: stop if <name> is a site somebody still needs
|
|
10
|
+
# nothing on the host: no odoo-bin, python, psql or npm outside the site's container
|
|
11
|
+
# the Community edition only: no other edition, no trial, no licence, no vendor account
|
|
12
|
+
|
|
13
|
+
1. bash cmd-odoo-project.sh <name> --install --add-users
|
|
14
|
+
(the default apps with demo data; add --apps <a,b> for another list of apps, --without-demo to leave the demo data out)
|
|
15
|
+
2. bash cmd-tools-odoo-cli.sh <name>
|
|
16
|
+
tell me the version, the address, the apps and the accounts it lists
|
|
17
|
+
3. bash cmd-tools-testing.sh <name>
|
|
18
|
+
webship-js, the step pack, the users registry and tests/features/site.feature
|
|
19
|
+
4. bash cmd-tools-testing.sh <name> --dry-run --path tests/features/site.feature
|
|
20
|
+
5. bash cmd-tools-testing.sh <name> --run --path tests/features/site.feature
|
|
21
|
+
the first feature expects the default apps: with another list of apps, tell me which scenarios do not apply instead of changing them
|
|
22
|
+
|
|
23
|
+
If a command fails, show the line that failed and stop. Do not retry with other flags.
|
|
24
|
+
When the feature is green: the address, the version, how many scenarios and steps passed.
|
|
25
|
+
Then ask me whether to keep the site or remove it with: bash cmd-tools-remove.sh <name>
|
|
26
|
+
"""
|
|
27
|
+
```
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: odoo-scenarios
|
|
3
|
+
description: Write and run webship-js scenarios for an Odoo Community site of the Webship Workspace with the Odoo step pack (`@webship-js/odoo-steps`) — the phrases of the pack by area (sessions, apps and menus, views and search, records, dialogs and the chatter, the website with its blog, shop, events and jobs), the handles of the users registry, and the workspace command that runs them in the site's container. Use when asked to "write a scenario for this Odoo site", "test the salesperson account", "which step is there for a kanban column", "add a feature for creating a contact", or when a `.feature` file of an Odoo project is being written or fixed.
|
|
4
|
+
argument-hint: '<site> [what to cover]'
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# odoo-scenarios
|
|
8
|
+
|
|
9
|
+
Scenarios for an Odoo Community site of a Webship Workspace (`~/workspace`, container-based, DDEV
|
|
10
|
+
by default), written from the steps of [`@webship-js/odoo-steps`](https://github.com/webship/odoo-steps)
|
|
11
|
+
and of [webship-js](https://github.com/webship/webship-js) itself, and run in the site's container
|
|
12
|
+
by the workspace's own command. It comes with the Odoo plugin (`@webship.co/workspace-odoo`), like
|
|
13
|
+
the builder (`cmd-odoo-project.sh`), the odoo-bin tool (`cmd-tools-odoo-cli.sh`) and the agents
|
|
14
|
+
`odoo-site-builder` and `odoo-tester`. The site is the Community edition, never the Enterprise
|
|
15
|
+
edition.
|
|
16
|
+
|
|
17
|
+
## Where everything is
|
|
18
|
+
|
|
19
|
+
| What | Where |
|
|
20
|
+
| --- | --- |
|
|
21
|
+
| The site | `~/workspace/<folder>/<site>`, at `https://<site>.ddev.site`, the login at `/web/login` (`<folder>` is a sites folder: `dev`, `test`, `sandboxes`, `demos`) |
|
|
22
|
+
| The suite's configuration | `<site>/cucumber.js`: the step definitions it loads and the users registry (`worldParameters.users`) |
|
|
23
|
+
| The features | `<site>/tests/features/*.feature` (`site.feature` is the first one the setup wrote) |
|
|
24
|
+
| The pack's steps | `<site>/node_modules/@webship-js/odoo-steps/tests/step-definitions/*.steps.js` |
|
|
25
|
+
| webship-js's steps | `<site>/node_modules/webship-js/tests/step-definitions/*.js` |
|
|
26
|
+
| The reports | `<site>/tests/reports/` |
|
|
27
|
+
|
|
28
|
+
## The order of work
|
|
29
|
+
|
|
30
|
+
1. **Make sure the testing stack is there.** From the sites folder:
|
|
31
|
+
```bash
|
|
32
|
+
cd ~/workspace/<folder>
|
|
33
|
+
bash cmd-tools-testing.sh <site>
|
|
34
|
+
```
|
|
35
|
+
It adds webship-js, the step pack, the users registry and `tests/features/site.feature`, and
|
|
36
|
+
makes sure the default accounts are on the site. It is safe to run again: it adds what is
|
|
37
|
+
missing and keeps what was changed.
|
|
38
|
+
2. **Know which apps the site has.** A scenario about an app that is not installed fails at its
|
|
39
|
+
first step:
|
|
40
|
+
```bash
|
|
41
|
+
bash cmd-tools-odoo-cli.sh <site> # the version, the apps, the accounts
|
|
42
|
+
bash cmd-tools-odoo-cli.sh <site> --install-apps project # only when an app is asked for
|
|
43
|
+
```
|
|
44
|
+
3. **Read the installed steps before writing a phrase.** They are the source of truth: the pack
|
|
45
|
+
moves, and a phrase from memory is a guess.
|
|
46
|
+
```bash
|
|
47
|
+
cd ~/workspace/<folder>/<site>
|
|
48
|
+
grep -hE "^(Given|When|Then)\(" node_modules/@webship-js/odoo-steps/tests/step-definitions/*.steps.js
|
|
49
|
+
```
|
|
50
|
+
Every step carries a comment block with five examples above it; open the file when a phrase
|
|
51
|
+
is not obvious.
|
|
52
|
+
4. **Look at the screen first** (the Playwright MCP browser, a tab of your own) when the scenario
|
|
53
|
+
is about a screen you have not seen: the label of a field, the name of a column and the items
|
|
54
|
+
of a menu are the site's own words, and a form does not always label its first field.
|
|
55
|
+
5. **Write the feature** in `<site>/tests/features/`, from phrases that exist (the lists below).
|
|
56
|
+
6. **Match every step without a browser**, then run the feature, then the suite:
|
|
57
|
+
```bash
|
|
58
|
+
cd ~/workspace/<folder>
|
|
59
|
+
bash cmd-tools-testing.sh <site> --dry-run --path tests/features/<name>.feature
|
|
60
|
+
bash cmd-tools-testing.sh <site> --run --path tests/features/<name>.feature
|
|
61
|
+
bash cmd-tools-testing.sh <site> --run --tags "@critical"
|
|
62
|
+
bash cmd-tools-testing.sh <site> --run
|
|
63
|
+
```
|
|
64
|
+
A dry run says `Undefined` for a phrase no definition matches: fix the phrase, do not write a
|
|
65
|
+
step for it.
|
|
66
|
+
|
|
67
|
+
## Accounts: a handle, never a password
|
|
68
|
+
|
|
69
|
+
A scenario logs in by a handle of the users registry. The default accounts are on the site
|
|
70
|
+
already (`bash cmd-tools-odoo-cli.sh <site> --add-users` adds them again if they were removed):
|
|
71
|
+
|
|
72
|
+
| Handle | Account | What it may do |
|
|
73
|
+
| --- | --- | --- |
|
|
74
|
+
| `admin` | `administrator` | Every installed app, and the settings |
|
|
75
|
+
| `salesperson` | `salesperson` | Sales and CRM, own documents only; no Invoicing |
|
|
76
|
+
| `accountant` | `accountant` | Invoicing; no Sales, no CRM |
|
|
77
|
+
| `employee` | `employee` | An internal user with no app of a role |
|
|
78
|
+
| `portal` | `portal` | A portal user: the website and `/my`, never the web client |
|
|
79
|
+
|
|
80
|
+
```gherkin
|
|
81
|
+
Given I am a logged in user with the "salesperson" user
|
|
82
|
+
Then I should be logged in as "salesperson"
|
|
83
|
+
And I should be in the web client
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## The phrases, by area
|
|
87
|
+
|
|
88
|
+
Each line is a phrase the pack defines, and each one passed on a site built with
|
|
89
|
+
`bash cmd-odoo-project.sh <site> --install --add-users` (the default apps with demo data; the
|
|
90
|
+
names in quotes are that site's). Most `should` steps also take the negative.
|
|
91
|
+
|
|
92
|
+
### Sessions
|
|
93
|
+
|
|
94
|
+
```gherkin
|
|
95
|
+
Given I am not logged in
|
|
96
|
+
Given I am on the login page
|
|
97
|
+
Given I am a logged in user with the "salesperson" user
|
|
98
|
+
When I log in as "salesperson" with password "not-the-password"
|
|
99
|
+
When I log out
|
|
100
|
+
Then I should see the login form
|
|
101
|
+
Then I should see a login error
|
|
102
|
+
Then I should be logged in as "salesperson"
|
|
103
|
+
Then I should not be logged in
|
|
104
|
+
Then I should be in the web client
|
|
105
|
+
Then I should be in the portal
|
|
106
|
+
When I open the user menu
|
|
107
|
+
Then I should see "Log out" in the user menu
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### Apps, menus and views
|
|
111
|
+
|
|
112
|
+
```gherkin
|
|
113
|
+
Then I should see the "CRM" app
|
|
114
|
+
Then I should not see the "Invoicing" app
|
|
115
|
+
When I open the "CRM" app
|
|
116
|
+
Then I should be in the "CRM" app
|
|
117
|
+
Then I should see the "Orders" menu
|
|
118
|
+
Then I should see "Quotations" in the breadcrumb
|
|
119
|
+
When I go back to "Contacts" in the breadcrumb
|
|
120
|
+
Then I should see the kanban view
|
|
121
|
+
When I switch to the list view
|
|
122
|
+
Then I should see the list view
|
|
123
|
+
Then I should see the "New" column
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### Records, search, dialogs and the chatter
|
|
127
|
+
|
|
128
|
+
```gherkin
|
|
129
|
+
When I create a new record
|
|
130
|
+
When I set the "Email" field to "suite-contact@example.com"
|
|
131
|
+
Then the form should have unsaved changes
|
|
132
|
+
When I save the record
|
|
133
|
+
Then the form should not have unsaved changes
|
|
134
|
+
Then the "Email" field should be "suite-contact@example.com"
|
|
135
|
+
Then I should see the chatter
|
|
136
|
+
When I log the note "Written by the suite."
|
|
137
|
+
Then I should see "Written by the suite." in the chatter
|
|
138
|
+
When I search the records for "A contact from the suite"
|
|
139
|
+
Then I should see the "A contact from the suite" record
|
|
140
|
+
Then I should see 1 record
|
|
141
|
+
When I select the "A contact from the suite" record
|
|
142
|
+
Then I should see 1 selected record
|
|
143
|
+
When I choose "Delete" in the Actions menu
|
|
144
|
+
Then I should see a dialog
|
|
145
|
+
When I confirm the dialog
|
|
146
|
+
Then I should see no records
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### The website
|
|
150
|
+
|
|
151
|
+
```gherkin
|
|
152
|
+
Then I should be on a website page
|
|
153
|
+
Then I should see the menu
|
|
154
|
+
Then I should see the footer
|
|
155
|
+
Then I should be on the blog page
|
|
156
|
+
Then I should be on the shop page
|
|
157
|
+
When I search the shop for "desk"
|
|
158
|
+
Then I should see shop search results for "desk"
|
|
159
|
+
When I open the first product in the shop
|
|
160
|
+
Then I should be on a product page
|
|
161
|
+
When I add the product to the cart
|
|
162
|
+
Then I should see "1" item in the cart
|
|
163
|
+
Then I should be on the events page
|
|
164
|
+
Then I should be on the jobs page
|
|
165
|
+
Then I should see job openings
|
|
166
|
+
Given I am on the contact page
|
|
167
|
+
Then I should see the contact form
|
|
168
|
+
Then I should be on the 404 page
|
|
169
|
+
Then I should be able to edit the website
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
`I am an anonymous user`, `I am on the homepage`, `I go to "/shop"`, `I should see "<text>"` and
|
|
173
|
+
`the response status code should be 200` are webship-js's own steps; its status codes, classes,
|
|
174
|
+
landmarks and accessibility audits are used as they are and never redefined for this platform.
|
|
175
|
+
|
|
176
|
+
## Traps found on a real site
|
|
177
|
+
|
|
178
|
+
- **A field is named by what the form shows, and the first field of a contact shows no label.**
|
|
179
|
+
`When I set the "Name" field to "…"` failed in Contacts: the form labels `Email`, `Phone`,
|
|
180
|
+
`Tags` and the others, and the name is a placeholder. The technical name passed:
|
|
181
|
+
`When I set the "name" field to "A contact from the suite"`. The failure message lists the
|
|
182
|
+
labels the form has.
|
|
183
|
+
- **`I should be able to edit the website` is a step for an internal user.** A visitor and a
|
|
184
|
+
portal user are not shown the website preview: they get the public page, and
|
|
185
|
+
`I should not be able to edit the website` passes for them. (With the pack before 2.1.1 it
|
|
186
|
+
failed there with `Expected the website preview of the web client`.) The positive form fails
|
|
187
|
+
for them and says to log in first.
|
|
188
|
+
- **Deleting a record is done from the list.** Search for it, switch to the list view, select
|
|
189
|
+
it, choose `Delete` in the Actions menu and confirm the dialog, as the example does.
|
|
190
|
+
- **A product in the cart is a quotation in Sales.** `When I add the product to the cart` passed
|
|
191
|
+
for a visitor and left a quotation behind that a visitor cannot remove. The examples stop at
|
|
192
|
+
the product page; a cart scenario belongs in a site that is rebuilt for the run.
|
|
193
|
+
- **The pages are the default apps'.** `/blog`, `/shop`, `/event`, `/jobs` and the pipeline
|
|
194
|
+
columns `New` and `Won` come with the apps and the demo data the builder installs. A site built
|
|
195
|
+
with `--apps` or `--without-demo` has its own.
|
|
196
|
+
- **The demo data has its own `portal` user.** The handle `portal` logs in as that account, with
|
|
197
|
+
the groups and the password of the default list.
|
|
198
|
+
|
|
199
|
+
## Rules
|
|
200
|
+
|
|
201
|
+
- **No account is created in a suite.** No user is added by a scenario or a hook. A role the
|
|
202
|
+
registry does not have is asked for, not made.
|
|
203
|
+
- **Never the workspace account.** The site's own administrator is not in the registry; `admin`
|
|
204
|
+
is the `administrator` default account.
|
|
205
|
+
- **No password in a feature file**, except where a wrong password is the subject.
|
|
206
|
+
- **No platform name in a step phrase**: `I open the "CRM" app`, `I should be in the web client`,
|
|
207
|
+
never a phrase that names the product. The same holds for a custom step.
|
|
208
|
+
- **No selector and no address when a step says it**: `the "Sales" app`, not the path of its
|
|
209
|
+
action.
|
|
210
|
+
- **What a scenario creates, it removes** in the same scenario, under a name nobody else uses.
|
|
211
|
+
- **Community only.** No scenario needs an app of another edition, a trial or a vendor account,
|
|
212
|
+
and nothing is sent to an outside service.
|
|
213
|
+
- **A custom step is the last resort**: look in the pack and in webship-js first, write it in
|
|
214
|
+
`<site>/tests/step-definitions/` with a comment block and examples, and say it may belong in
|
|
215
|
+
the pack.
|
|
216
|
+
- **Everything runs in the container**, through `cmd-tools-testing.sh`. Never `npx cucumber-js`
|
|
217
|
+
or `npx playwright` on the host.
|
|
218
|
+
- **A failing scenario is a result.** No `@wip`, no longer timeout, no looser assertion to turn a
|
|
219
|
+
run green: say what the site did.
|
|
220
|
+
|
|
221
|
+
## Examples that run
|
|
222
|
+
|
|
223
|
+
`examples/` holds three features that pass on a site built with
|
|
224
|
+
`bash cmd-odoo-project.sh <site> --install --add-users`. Copy one into the suite and run it:
|
|
225
|
+
|
|
226
|
+
```bash
|
|
227
|
+
cp ~/workspace/ai-skills/odoo-scenarios/examples/apps-and-views.feature ~/workspace/<folder>/<site>/tests/features/
|
|
228
|
+
cd ~/workspace/<folder>
|
|
229
|
+
bash cmd-tools-testing.sh <site> --run --path tests/features/apps-and-views.feature
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
| Feature | What it shows |
|
|
233
|
+
| --- | --- |
|
|
234
|
+
| `examples/apps-and-views.feature` | A salesperson in the pipeline and in the quotations, an employee with no app of a role, the user menu |
|
|
235
|
+
| `examples/contact-lifecycle.feature` | An administrator creating a contact, logging a note, finding it and deleting it: a record a scenario creates and removes |
|
|
236
|
+
| `examples/website.feature` | A visitor on the front page, the blog, the shop, the events, the jobs and the contact page, an address with no page, and a portal user kept out of the web client |
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
Feature: Each account works in the apps of its role
|
|
2
|
+
As the owner of the site
|
|
3
|
+
I want every account to open the apps of its role, with their views and menus
|
|
4
|
+
So that a change of groups or of an app is caught by the suite
|
|
5
|
+
|
|
6
|
+
# The accounts are the default ones; a scenario logs in by a handle of the users registry.
|
|
7
|
+
|
|
8
|
+
Scenario: A salesperson works in the pipeline
|
|
9
|
+
Given I am a logged in user with the "salesperson" user
|
|
10
|
+
When I open the "CRM" app
|
|
11
|
+
Then I should be in the "CRM" app
|
|
12
|
+
And I should see the kanban view
|
|
13
|
+
And I should see the "New" column
|
|
14
|
+
And I should see the "Won" column
|
|
15
|
+
When I switch to the list view
|
|
16
|
+
Then I should see the list view
|
|
17
|
+
|
|
18
|
+
Scenario: A salesperson opens the quotations
|
|
19
|
+
Given I am a logged in user with the "salesperson" user
|
|
20
|
+
When I open the "Sales" app
|
|
21
|
+
Then I should be in the "Sales" app
|
|
22
|
+
And I should see "Quotations" in the breadcrumb
|
|
23
|
+
And I should see the "Orders" menu
|
|
24
|
+
|
|
25
|
+
Scenario: An employee has the web client and no app of a role
|
|
26
|
+
Given I am a logged in user with the "employee" user
|
|
27
|
+
Then I should be in the web client
|
|
28
|
+
But I should not see the "Sales" app
|
|
29
|
+
And I should not see the "Settings" app
|
|
30
|
+
|
|
31
|
+
Scenario: The user menu ends the session
|
|
32
|
+
Given I am a logged in user with the "accountant" user
|
|
33
|
+
When I open the user menu
|
|
34
|
+
Then I should see "Log out" in the user menu
|
|
35
|
+
When I log out
|
|
36
|
+
Then I should not be logged in
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
Feature: A contact is written and removed again
|
|
2
|
+
As an administrator
|
|
3
|
+
I want to create a contact, note something on it, find it and delete it
|
|
4
|
+
So that the suite proves records, the chatter and the search work, and leaves the site as it found it
|
|
5
|
+
|
|
6
|
+
Scenario: The administrator creates a contact, finds it in the list and deletes it
|
|
7
|
+
Given I am a logged in user with the "admin" user
|
|
8
|
+
When I open the "Contacts" app
|
|
9
|
+
And I create a new record
|
|
10
|
+
And I set the "name" field to "A contact written by a scenario"
|
|
11
|
+
And I set the "Email" field to "scenario-contact@example.com"
|
|
12
|
+
Then the form should have unsaved changes
|
|
13
|
+
When I save the record
|
|
14
|
+
Then the form should not have unsaved changes
|
|
15
|
+
And the "Email" field should be "scenario-contact@example.com"
|
|
16
|
+
And I should see the chatter
|
|
17
|
+
When I log the note "Written and removed by the suite."
|
|
18
|
+
Then I should see "Written and removed by the suite." in the chatter
|
|
19
|
+
When I go back to "Contacts" in the breadcrumb
|
|
20
|
+
And I search the records for "A contact written by a scenario"
|
|
21
|
+
Then I should see the "A contact written by a scenario" record
|
|
22
|
+
And I should see 1 record
|
|
23
|
+
When I switch to the list view
|
|
24
|
+
And I select the "A contact written by a scenario" record
|
|
25
|
+
Then I should see 1 selected record
|
|
26
|
+
When I choose "Delete" in the Actions menu
|
|
27
|
+
Then I should see a dialog
|
|
28
|
+
When I confirm the dialog
|
|
29
|
+
Then I should see no records
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
Feature: A visitor reads the website
|
|
2
|
+
As the owner of the site
|
|
3
|
+
I want the pages of the website apps to be served to a visitor
|
|
4
|
+
So that an app or a theme that breaks the website is caught by the suite
|
|
5
|
+
|
|
6
|
+
# For a site built with the default apps: the blog, the shop, the events and the jobs.
|
|
7
|
+
|
|
8
|
+
Scenario: The front page has its menu and its footer
|
|
9
|
+
Given I am an anonymous user
|
|
10
|
+
And I am on the homepage
|
|
11
|
+
Then I should be on a website page
|
|
12
|
+
And I should see the menu
|
|
13
|
+
And I should see the footer
|
|
14
|
+
|
|
15
|
+
Scenario: Each website app has its page
|
|
16
|
+
Given I am an anonymous user
|
|
17
|
+
When I go to "/blog"
|
|
18
|
+
Then I should be on the blog page
|
|
19
|
+
When I go to "/event"
|
|
20
|
+
Then I should be on the events page
|
|
21
|
+
When I go to "/jobs"
|
|
22
|
+
Then I should be on the jobs page
|
|
23
|
+
And I should see job openings
|
|
24
|
+
Given I am on the contact page
|
|
25
|
+
Then I should see the contact form
|
|
26
|
+
|
|
27
|
+
Scenario: The shop lists products and finds one
|
|
28
|
+
Given I am an anonymous user
|
|
29
|
+
When I go to "/shop"
|
|
30
|
+
Then I should be on the shop page
|
|
31
|
+
When I search the shop for "desk"
|
|
32
|
+
Then I should see shop search results for "desk"
|
|
33
|
+
When I open the first product in the shop
|
|
34
|
+
Then I should be on a product page
|
|
35
|
+
|
|
36
|
+
Scenario: An address with no page is not found, and a portal user stays out of the web client
|
|
37
|
+
Given I am an anonymous user
|
|
38
|
+
When I go to "/this-page-does-not-exist"
|
|
39
|
+
Then I should be on the 404 page
|
|
40
|
+
Given I am a logged in user with the "portal" user
|
|
41
|
+
When I go to "/web"
|
|
42
|
+
Then I should be in the portal
|
|
43
|
+
And I should not be in the web client
|
package/dist/src/index.d.ts
CHANGED
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
*
|
|
4
4
|
* What the package carries is placed by the installer from the manifest: the builder and the
|
|
5
5
|
* odoo-bin tool in the sites folders, their functions, argparse and the accounts script under
|
|
6
|
-
* core/scripts/plugins/odoo/,
|
|
6
|
+
* core/scripts/plugins/odoo/, its AI items (ai/) in the AI folders. The dashboard needs nothing
|
|
7
7
|
* drawn for it: the builder is in the Build list because it is a cmd-*-project.sh, the row menus
|
|
8
|
-
* are the core's, the
|
|
8
|
+
* are the core's, the AI items are listed like any other. What register() adds is what the
|
|
9
9
|
* assistant is told.
|
|
10
10
|
*
|
|
11
11
|
* Everything the dashboard is asked for goes through `api`; this package requires nothing from the
|
|
@@ -18,6 +18,12 @@ export declare const PLATFORM = "odoo";
|
|
|
18
18
|
export declare const COMMANDS: string[];
|
|
19
19
|
/** The agents the installer places in the AI Agents folder. */
|
|
20
20
|
export declare const AGENTS: string[];
|
|
21
|
+
/** The skill the installer places in the AI Skills folder (a folder each, with its SKILL.md). */
|
|
22
|
+
export declare const SKILLS: string[];
|
|
23
|
+
/** The slash command the installer places in the AI Commands folder. */
|
|
24
|
+
export declare const AI_COMMANDS: string[];
|
|
25
|
+
/** The prompt the installer places in the AI Prompts folder: a whole launch command for a new session. */
|
|
26
|
+
export declare const PROMPTS: string[];
|
|
21
27
|
/** What the assistant is told about Odoo in this workspace. */
|
|
22
28
|
export declare function assistantContext(): string;
|
|
23
29
|
export declare function register(api: PluginApi): void;
|
package/dist/src/index.js
CHANGED
|
@@ -4,16 +4,16 @@
|
|
|
4
4
|
*
|
|
5
5
|
* What the package carries is placed by the installer from the manifest: the builder and the
|
|
6
6
|
* odoo-bin tool in the sites folders, their functions, argparse and the accounts script under
|
|
7
|
-
* core/scripts/plugins/odoo/,
|
|
7
|
+
* core/scripts/plugins/odoo/, its AI items (ai/) in the AI folders. The dashboard needs nothing
|
|
8
8
|
* drawn for it: the builder is in the Build list because it is a cmd-*-project.sh, the row menus
|
|
9
|
-
* are the core's, the
|
|
9
|
+
* are the core's, the AI items are listed like any other. What register() adds is what the
|
|
10
10
|
* assistant is told.
|
|
11
11
|
*
|
|
12
12
|
* Everything the dashboard is asked for goes through `api`; this package requires nothing from the
|
|
13
13
|
* dashboard's own files, so it can be installed from npm and removed without a trace.
|
|
14
14
|
*/
|
|
15
15
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
-
exports.AGENTS = exports.COMMANDS = exports.PLATFORM = void 0;
|
|
16
|
+
exports.PROMPTS = exports.AI_COMMANDS = exports.SKILLS = exports.AGENTS = exports.COMMANDS = exports.PLATFORM = void 0;
|
|
17
17
|
exports.assistantContext = assistantContext;
|
|
18
18
|
exports.register = register;
|
|
19
19
|
/** The plugin's name, which its functions are named after. */
|
|
@@ -22,6 +22,12 @@ exports.PLATFORM = 'odoo';
|
|
|
22
22
|
exports.COMMANDS = ['cmd-odoo-project.sh', 'cmd-tools-odoo-cli.sh'];
|
|
23
23
|
/** The agents the installer places in the AI Agents folder. */
|
|
24
24
|
exports.AGENTS = ['odoo-site-builder', 'odoo-tester'];
|
|
25
|
+
/** The skill the installer places in the AI Skills folder (a folder each, with its SKILL.md). */
|
|
26
|
+
exports.SKILLS = ['odoo-scenarios'];
|
|
27
|
+
/** The slash command the installer places in the AI Commands folder. */
|
|
28
|
+
exports.AI_COMMANDS = ['odoo-test'];
|
|
29
|
+
/** The prompt the installer places in the AI Prompts folder: a whole launch command for a new session. */
|
|
30
|
+
exports.PROMPTS = ['odoo-build-and-test'];
|
|
25
31
|
/** What the assistant is told about Odoo in this workspace. */
|
|
26
32
|
function assistantContext() {
|
|
27
33
|
return [
|
|
@@ -33,6 +39,8 @@ function assistantContext() {
|
|
|
33
39
|
'`--add-users` adds the default accounts (one per kind of user).',
|
|
34
40
|
'`bash cmd-tools-testing.sh <name>` sets up webship-js with the Odoo step pack; `--run` runs the suite.',
|
|
35
41
|
`For Odoo work, hand over to the agents ${exports.AGENTS.map((a) => `\`${a}\``).join(' and ')}.`,
|
|
42
|
+
`The plugin also places the skill ${exports.SKILLS.map((a) => `\`${a}\``).join(', ')} (the step pack's phrases, by area) in ai-skills/,`,
|
|
43
|
+
`the command ${exports.AI_COMMANDS.map((a) => `\`/${a} <site>\``).join(', ')} in ai-commands/ and the prompt ${exports.PROMPTS.map((a) => `\`${a}\``).join(' and ')} in ai-prompts/.`,
|
|
36
44
|
'Community only: never the Enterprise edition, never a vendor account. Never run odoo, python or psql on the host for a project.',
|
|
37
45
|
'The example builder cmd-odoo20-project.sh of a sites folder is a different, simpler build; this plugin leaves it as it is.',
|
|
38
46
|
].join(' ');
|
package/dist/src/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;GAYG;;;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;GAYG;;;AAuBH,4CAeC;AAED,4BAEC;AAtCD,8DAA8D;AACjD,QAAA,QAAQ,GAAG,MAAM,CAAC;AAE/B,+DAA+D;AAClD,QAAA,QAAQ,GAAG,CAAC,qBAAqB,EAAE,uBAAuB,CAAC,CAAC;AAEzE,+DAA+D;AAClD,QAAA,MAAM,GAAG,CAAC,mBAAmB,EAAE,aAAa,CAAC,CAAC;AAE3D,iGAAiG;AACpF,QAAA,MAAM,GAAG,CAAC,gBAAgB,CAAC,CAAC;AAEzC,wEAAwE;AAC3D,QAAA,WAAW,GAAG,CAAC,WAAW,CAAC,CAAC;AAEzC,0GAA0G;AAC7F,QAAA,OAAO,GAAG,CAAC,qBAAqB,CAAC,CAAC;AAE/C,+DAA+D;AAC/D,SAAgB,gBAAgB;IAC9B,OAAO;QACL,mFAAmF;QACnF,4GAA4G;QAC5G,gGAAgG;QAChG,0HAA0H;QAC1H,gHAAgH;QAChH,iEAAiE;QACjE,wGAAwG;QACxG,0CAA0C,cAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG;QACxF,oCAAoC,cAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,oDAAoD;QAChI,eAAe,mBAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,mCAAmC,eAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,kBAAkB;QACrK,iIAAiI;QACjI,4HAA4H;KAC7H,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,145 @@
|
|
|
1
|
+
# A plugin carries its own items
|
|
2
|
+
|
|
3
|
+
Every `@webship.co/workspace-<name>` plugin manages what belongs to it: its `cmd-*.sh` commands and
|
|
4
|
+
its AI items (agents, skills, commands, prompts). The package holds them, the manifest names them,
|
|
5
|
+
and `plugins.sh --install <name>` lists each one in the workspace folder of its kind, when that
|
|
6
|
+
folder is an active workspace folder. `--uninstall` takes them away again. The reference is
|
|
7
|
+
[`@webship.co/workspace-wordpress`](https://github.com/webship/workspace-wordpress), and this plugin
|
|
8
|
+
follows it; below, `<p>` is the plugin's name.
|
|
9
|
+
|
|
10
|
+
## The layout
|
|
11
|
+
|
|
12
|
+
```text
|
|
13
|
+
commands/cmd-<p>-project.sh cmd-*.sh scripts only: builders and tools, placed in workspace folders
|
|
14
|
+
commands/cmd-tools-<p>-cli.sh
|
|
15
|
+
ai/agents/<p>-<role>.md one file per agent
|
|
16
|
+
ai/skills/<p>-<topic>/SKILL.md one folder per skill; every file in it is placed (examples/, references/)
|
|
17
|
+
ai/commands/<p>-<verb>.md one file per slash command
|
|
18
|
+
ai/prompts/<p>-<task>.md one file per prompt
|
|
19
|
+
tests/items.test.ts the shape of every item, and that it names nothing that does not exist
|
|
20
|
+
tests/fixtures/step-definitions.txt the step definitions the items' phrases are checked against (a plugin with a step pack)
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
`commands/` is taken by the `cmd-*.sh` scripts, so the AI items live under `ai/`, one folder per
|
|
24
|
+
kind, named like the manifest's `ai` keys. The installer places an item by the last part of its
|
|
25
|
+
path, whatever folder the package keeps it in, so a plugin that kept its agents in `agents/` moves
|
|
26
|
+
them with `git mv agents ai/agents` and changes two lines of its manifest.
|
|
27
|
+
|
|
28
|
+
## The manifest
|
|
29
|
+
|
|
30
|
+
```json
|
|
31
|
+
"files": ["dist/src", "ai", "commands", "docs", "features", "scripts", "testing", "README.md"],
|
|
32
|
+
"workspacePlugin": {
|
|
33
|
+
"name": "<p>",
|
|
34
|
+
"needs": [["dev", "test", "sandboxes", "demos"], "ai-agents", "ai-skills", "ai-commands", "ai-prompts"],
|
|
35
|
+
"commands": { "types": ["sites"], "workspaces": ["dev", "test", "sandboxes", "demos"],
|
|
36
|
+
"files": ["commands/cmd-<p>-project.sh", "commands/cmd-tools-<p>-cli.sh"] },
|
|
37
|
+
"ai": {
|
|
38
|
+
"agents": ["ai/agents/<p>-site-builder.md", "ai/agents/<p>-tester.md"],
|
|
39
|
+
"skills": ["ai/skills/<p>-scenarios"],
|
|
40
|
+
"commands": ["ai/commands/<p>-test.md"],
|
|
41
|
+
"prompts": ["ai/prompts/<p>-build-and-test.md"]
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
- `ai` is in `files`, or the items are not in the published package.
|
|
47
|
+
- A skill is named by its folder, with no `/SKILL.md` and no trailing slash.
|
|
48
|
+
- `needs` names the folder of every kind the plugin ships, after the folder its commands need. A
|
|
49
|
+
plugin with no `cmd-*.sh` for a sites folder leaves the first entry out; a kind it does not ship
|
|
50
|
+
is left out of `ai` and of `needs`.
|
|
51
|
+
|
|
52
|
+
| Kind | Lands in | Claude Code reads it from |
|
|
53
|
+
| --- | --- | --- |
|
|
54
|
+
| `commands.files` | every active folder `commands.workspaces` names, else every active folder of `commands.types` | the folder itself: `bash cmd-….sh` |
|
|
55
|
+
| `ai.agents` | `ai-agents/<name>.md` | `~/.claude/agents`, after Install |
|
|
56
|
+
| `ai.skills` | `ai-skills/<name>/` | `~/.claude/skills`, after Install |
|
|
57
|
+
| `ai.commands` | `ai-commands/<name>.md` | `~/.claude/commands`, after Install: `/<name>` |
|
|
58
|
+
| `ai.prompts` | `ai-prompts/<name>.md` | nothing: the New screen form lists it as a template for a new session |
|
|
59
|
+
|
|
60
|
+
## The shape of each kind
|
|
61
|
+
|
|
62
|
+
| Kind | Shape |
|
|
63
|
+
| --- | --- |
|
|
64
|
+
| Agent | Frontmatter `name` (the file's name), `description` (when to use it, with the phrases a person says), `model: fable`, `tools`; then what it does, the commands it runs, its rules |
|
|
65
|
+
| Skill | `SKILL.md` with frontmatter `name` (the folder's name) and `description` (what it does, then `Use when …`); files beside it for what is too long or is meant to be copied |
|
|
66
|
+
| Command | Frontmatter `description` and `argument-hint`, no `name` (the file names it); the body reads what was typed from `$ARGUMENTS` |
|
|
67
|
+
| Prompt | No frontmatter. One sentence that says what it is for, then a fenced block holding the whole launch command: `claude --permission-mode bypassPermissions """` … `"""`, with `<placeholders>` to fill in and a `#` line that says where it runs |
|
|
68
|
+
|
|
69
|
+
Names start with the plugin's name (`<p>-…`): an item that is already in the folder under the same
|
|
70
|
+
name is kept, so a name another plugin could also choose would never be placed. A command and a
|
|
71
|
+
prompt never share a name: both end in `~/.claude/commands`.
|
|
72
|
+
|
|
73
|
+
## What an item may say
|
|
74
|
+
|
|
75
|
+
Nothing generic and nothing invented. An item is about what this plugin does in the workspace, and
|
|
76
|
+
every command, flag, path and step phrase in it exists:
|
|
77
|
+
|
|
78
|
+
- commands and flags: the plugin's own (`scripts/args/*.sh`) and the workspace's (`cmd-tools-testing.sh`
|
|
79
|
+
and its flags, `cmd-tools-remove.sh`, `cmd-tools-clone.sh --to`, `cmd-tools-ai-items.sh --install`);
|
|
80
|
+
- step phrases: the plugin's step pack and webship-js, as installed in a real project;
|
|
81
|
+
- the workspace is container-based (DDEV by default); no platform name in a step phrase; no
|
|
82
|
+
account created by a scenario; no password, no personal path, addresses at `example.com`.
|
|
83
|
+
|
|
84
|
+
Run every command an item tells its reader to run, and every scenario it shows, on a real site
|
|
85
|
+
before it is pushed. Two of the three example features of the reference failed on their first real
|
|
86
|
+
run, each on a phrase that exists and matched in a dry run.
|
|
87
|
+
|
|
88
|
+
## The tests to copy
|
|
89
|
+
|
|
90
|
+
`tests/items.test.ts` checks, with no site and no network:
|
|
91
|
+
|
|
92
|
+
1. the manifest: one list per kind, each item under `ai/<kind>/`, in the package, named `<p>-…`,
|
|
93
|
+
`ai` in `files`, the folder of each kind in `needs`, no command and prompt of the same name;
|
|
94
|
+
2. the shape of each kind (the table above; the two expressions the dashboard reads a prompt with);
|
|
95
|
+
3. every `cmd-*.sh` an item names is the plugin's or the workspace's, with flags that exist;
|
|
96
|
+
4. every step in a `gherkin` block or a `.feature` file matches a definition in
|
|
97
|
+
`tests/fixtures/step-definitions.txt`, names no platform and carries no password;
|
|
98
|
+
5. the words: container-based, no personal value, the README lists every item.
|
|
99
|
+
|
|
100
|
+
Refresh the fixture from a project whose testing stack is set up, whenever the pack's release
|
|
101
|
+
line changes (`<pack>` is the plugin's step pack):
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
cd ~/workspace/<folder>/<site>
|
|
105
|
+
{ echo "# <pack> <version> and webship-js <version>" ;
|
|
106
|
+
grep -hE "^(Given|When|Then)\(/" node_modules/<pack>/tests/step-definitions/*.steps.js node_modules/webship-js/tests/step-definitions/*.steps.js \
|
|
107
|
+
| sed -nE 's/^(Given|When|Then)\(\/(.*)\/, (async )?function.*/\2/p' | sort -u ; } > step-definitions.txt
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
`tests/needs.test.ts` holds the exact `needs` list, and `tests/plugin.test.ts` that every file the
|
|
111
|
+
manifest names ships.
|
|
112
|
+
|
|
113
|
+
## Prove it on a fresh workspace
|
|
114
|
+
|
|
115
|
+
Never in a workspace somebody works in. `webship-workspace init <folder>` makes an empty one.
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
npm pack # in the plugin: the tarball of the branch
|
|
119
|
+
cd <the fresh workspace>
|
|
120
|
+
bash core/scripts/plugins.sh --require <path>/webship.co-workspace-<p>-<version>.tgz # says what it needs
|
|
121
|
+
bash core/scripts/plugins.sh --activate <p> # stops: lists what is not here, changes nothing
|
|
122
|
+
bash core/scripts/plugins.sh --activate <p> --with-needs # adds the folders, then activates
|
|
123
|
+
bash core/scripts/plugins.sh --install <p> # "placed …" once per file
|
|
124
|
+
ls dev ai-agents ai-skills ai-commands ai-prompts # each item in its folder
|
|
125
|
+
bash core/scripts/plugins.sh --list # needs: … met by …
|
|
126
|
+
bash core/scripts/plugins.sh --uninstall <p> # "removed …" once per file
|
|
127
|
+
grep -c "<p>" core/config/plugins.installed.yml # 0: the record is gone
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
Then, installed again: build one site with the builder, run each command the items name, copy the
|
|
131
|
+
skill's examples into the suite and run them, look at the four AI folders on the dashboard, and
|
|
132
|
+
remove the site with `cmd-tools-remove.sh`.
|
|
133
|
+
|
|
134
|
+
## What was found on the way
|
|
135
|
+
|
|
136
|
+
- A phrase that matches in a dry run can still fail: a step may need another one before it
|
|
137
|
+
(`I should see the page title` needs `Given I am on a page`), or assert something the site does
|
|
138
|
+
not do as built. Only a real run tells.
|
|
139
|
+
- Content a failed scenario created stays on the site. Name it so it is found, and remove it
|
|
140
|
+
through the CLI tool before the next run (an entry in the trash is not in a list of every status).
|
|
141
|
+
- A folder that is not active gets nothing: the install says `skipped <n> <kind>` for it, and
|
|
142
|
+
places the items when the folder is added. With the folder in `needs`, `--activate` and
|
|
143
|
+
`--install` stop before that and offer to add it.
|
|
144
|
+
- An item a person edited in its folder is kept by `--install` and by `--uninstall`: the record
|
|
145
|
+
holds the hash of what was placed.
|
package/features/odoo.feature
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
Feature: The Odoo plugin on the dashboard
|
|
2
|
-
Once the plugin is activated and installed, the sites folders offer the Odoo builder,
|
|
3
|
-
AI
|
|
2
|
+
Once the plugin is activated and installed, the sites folders offer the Odoo builder, each
|
|
3
|
+
AI folder lists the items of its kind the plugin ships, and the Plugins page lists the plugin
|
|
4
|
+
with its steps.
|
|
4
5
|
|
|
5
6
|
Scenario: The plugin is listed on the Plugins page
|
|
6
7
|
Given I am on "/settings/plugins"
|
|
@@ -15,3 +16,15 @@ Feature: The Odoo plugin on the dashboard
|
|
|
15
16
|
Given I am on "/ai-agents"
|
|
16
17
|
Then I should see "odoo-site-builder"
|
|
17
18
|
And I should see "odoo-tester"
|
|
19
|
+
|
|
20
|
+
Scenario: The AI Skills folder lists the skill the plugin ships
|
|
21
|
+
Given I am on "/ai-skills"
|
|
22
|
+
Then I should see "odoo-scenarios"
|
|
23
|
+
|
|
24
|
+
Scenario: The AI Commands folder lists the command the plugin ships
|
|
25
|
+
Given I am on "/ai-commands"
|
|
26
|
+
Then I should see "odoo-test"
|
|
27
|
+
|
|
28
|
+
Scenario: The AI Prompts folder lists the prompt the plugin ships
|
|
29
|
+
Given I am on "/ai-prompts"
|
|
30
|
+
Then I should see "odoo-build-and-test"
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@webship.co/workspace-odoo",
|
|
3
|
-
"version": "1.0.
|
|
4
|
-
"description": "Odoo Community for Webship Workspace: the builder (`cmd-odoo-project.sh`) and the odoo-bin tool in every sites folder, the default accounts, the Odoo step pack wired into the testing setup, and
|
|
3
|
+
"version": "1.0.9",
|
|
4
|
+
"description": "Odoo Community for Webship Workspace: the builder (`cmd-odoo-project.sh`) and the odoo-bin tool in every sites folder, the default accounts, the Odoo step pack wired into the testing setup, and its AI items in their folders: two agents, a skill, a command and a prompt.",
|
|
5
5
|
"main": "dist/src/index.js",
|
|
6
6
|
"types": "dist/src/index.d.ts",
|
|
7
7
|
"license": "ISC",
|
|
@@ -11,8 +11,9 @@
|
|
|
11
11
|
},
|
|
12
12
|
"files": [
|
|
13
13
|
"dist/src",
|
|
14
|
-
"
|
|
14
|
+
"ai",
|
|
15
15
|
"commands",
|
|
16
|
+
"docs",
|
|
16
17
|
"features",
|
|
17
18
|
"scripts",
|
|
18
19
|
"testing",
|
|
@@ -27,6 +28,18 @@
|
|
|
27
28
|
"workspacePlugin": {
|
|
28
29
|
"name": "odoo",
|
|
29
30
|
"label": "Odoo",
|
|
31
|
+
"needs": [
|
|
32
|
+
[
|
|
33
|
+
"dev",
|
|
34
|
+
"test",
|
|
35
|
+
"sandboxes",
|
|
36
|
+
"demos"
|
|
37
|
+
],
|
|
38
|
+
"ai-agents",
|
|
39
|
+
"ai-skills",
|
|
40
|
+
"ai-commands",
|
|
41
|
+
"ai-prompts"
|
|
42
|
+
],
|
|
30
43
|
"commands": {
|
|
31
44
|
"types": [
|
|
32
45
|
"sites"
|
|
@@ -57,8 +70,17 @@
|
|
|
57
70
|
},
|
|
58
71
|
"ai": {
|
|
59
72
|
"agents": [
|
|
60
|
-
"agents/odoo-site-builder.md",
|
|
61
|
-
"agents/odoo-tester.md"
|
|
73
|
+
"ai/agents/odoo-site-builder.md",
|
|
74
|
+
"ai/agents/odoo-tester.md"
|
|
75
|
+
],
|
|
76
|
+
"skills": [
|
|
77
|
+
"ai/skills/odoo-scenarios"
|
|
78
|
+
],
|
|
79
|
+
"commands": [
|
|
80
|
+
"ai/commands/odoo-test.md"
|
|
81
|
+
],
|
|
82
|
+
"prompts": [
|
|
83
|
+
"ai/prompts/odoo-build-and-test.md"
|
|
62
84
|
]
|
|
63
85
|
},
|
|
64
86
|
"features": [
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
|
|
26
26
|
# The step pack an Odoo project is tested with, and the release line it is required at.
|
|
27
27
|
readonly ODOO_STEPS_PACKAGE='@webship-js/odoo-steps';
|
|
28
|
-
readonly ODOO_STEPS_VERSION='^2.1.
|
|
28
|
+
readonly ODOO_STEPS_VERSION='^2.1.1';
|
|
29
29
|
|
|
30
30
|
# The one database of a project (the container tool's own), and the port Odoo listens on.
|
|
31
31
|
readonly ODOO_DATABASE='db';
|