Prior behaviour: lm.add_library(LIBRARY_NAME) was called with a string,
which always hits the placeholder overload of ScriptLibManObject.add_library
(see helpme-codesys.com "ScriptLibManObject" / local SP22 stub
ScriptLib/Stubs/scriptengine/ScriptLibManObject.pyi). If the named
placeholder is not registered in the IDE, the resulting reference fails
to resolve at load time and the next project open throws
Library Manager: Error: Could not open library 'X'.
(Reason: The placeholder library 'X' could not be resolved.)
after which script_engine.projects.primary returns None and the project
is effectively bricked until the binary is reverted. add_library reported
SUCCESS in this scenario.
Fix:
1. Pre-resolve LIBRARY_NAME via the IDE-level
library_manager.find_library(name) global. If found, pass the
resulting ManagedLib to lm.add_library(...) -- the V3.5.5.0 ManagedLib
overload which produces a managed reference instead of a placeholder.
2. After the add, walk lm.references to locate the new entry and verify
it resolved (managed -> always; placeholder -> non-empty
effective_resolution per ScriptPlaceholderReference in the stub).
3. If the reference did not resolve, call lm.remove_library(name) to back
out the bad reference and refuse to save the project, returning an
actionable error instead.
Also tightened the libman lookup to use the documented
has_library_manager / get_library_manager() container API
(ScriptLibManObjectContainer in the stub) instead of name-searching for
"Library Manager" as a tree node, matching what list_project_libraries.py
already does. The legacy name-search fallback is preserved for older SPs.
Regression test added in tests/integration/e2e.test.ts asserting the
rendered script template carries the resolution gate, the managed-overload
preference, the back-out call, and that primary_project.save() in the
add_library body lives downstream of the _is_resolved gate.
Followup: lm.remove_library(name) is documented for SP22 and is the
clean back-out path. On SPs that lack remove_library (none observed in
the 3.5.21+ docs but possible on truly old branches) the script reports
the constraint and exits non-zero rather than silently saving a bad
reference.
|
||
|---|---|---|
| .. | ||
| e2e.test.ts | ||
| README.md | ||
Manual CODESYS Integration Tests
These tests require a real CODESYS installation and cannot run in CI.
Prerequisites
- CODESYS 3.5 SP19 or SP21 installed
- No other CODESYS instances running
- Node.js 18+
Steps
1. Build the package
npm run build
2. Test persistent mode
node dist/bin.js \
--codesys-path "C:\path\to\CODESYS.exe" \
--codesys-profile "CODESYS V3.5 SP21 Patch 3" \
--mode persistent \
--verbose
Verify:
- CODESYS UI opens
- Console shows "CODESYS watcher is ready"
- The MCP server accepts connections
3. Test headless fallback
node dist/bin.js \
--codesys-path "C:\path\to\CODESYS.exe" \
--codesys-profile "CODESYS V3.5 SP21 Patch 3" \
--mode headless
4. Test --detect flag
node dist/bin.js --detect
Verify: Lists installed CODESYS versions.
5. Ctrl+C shutdown
- Press Ctrl+C during persistent mode
- Verify CODESYS shuts down cleanly