@solidxai/core 0.1.13-beta.2 → 0.1.13-beta.21
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/CHANGELOG.md +10107 -0
- package/CLAUDE.md +5 -6
- package/README.md +19 -0
- package/dist/commands/run-tests.command.d.ts +9 -1
- package/dist/commands/run-tests.command.d.ts.map +1 -1
- package/dist/commands/run-tests.command.js +69 -6
- package/dist/commands/run-tests.command.js.map +1 -1
- package/dist/commands/seed.command.d.ts +2 -0
- package/dist/commands/seed.command.d.ts.map +1 -1
- package/dist/commands/seed.command.js +21 -0
- package/dist/commands/seed.command.js.map +1 -1
- package/dist/config/cache.options.d.ts.map +1 -1
- package/dist/config/cache.options.js +2 -2
- package/dist/config/cache.options.js.map +1 -1
- package/dist/constants/chatter-message.constants.d.ts +1 -0
- package/dist/constants/chatter-message.constants.d.ts.map +1 -1
- package/dist/constants/chatter-message.constants.js +3 -1
- package/dist/constants/chatter-message.constants.js.map +1 -1
- package/dist/constants/draft-publish-fields.d.ts +2 -0
- package/dist/constants/draft-publish-fields.d.ts.map +1 -0
- package/dist/constants/draft-publish-fields.js +5 -0
- package/dist/constants/draft-publish-fields.js.map +1 -0
- package/dist/constants/error-messages.d.ts +7 -0
- package/dist/constants/error-messages.d.ts.map +1 -1
- package/dist/constants/error-messages.js +7 -0
- package/dist/constants/error-messages.js.map +1 -1
- package/dist/constants/media-file-types.d.ts +12 -0
- package/dist/constants/media-file-types.d.ts.map +1 -1
- package/dist/constants/media-file-types.js +66 -1
- package/dist/constants/media-file-types.js.map +1 -1
- package/dist/constants/success-messages.d.ts +3 -0
- package/dist/constants/success-messages.d.ts.map +1 -1
- package/dist/constants/success-messages.js +3 -0
- package/dist/constants/success-messages.js.map +1 -1
- package/dist/constants/user.constants.d.ts +2 -0
- package/dist/constants/user.constants.d.ts.map +1 -0
- package/dist/constants/user.constants.js +5 -0
- package/dist/constants/user.constants.js.map +1 -0
- package/dist/controllers/action-metadata.controller.d.ts +1 -1
- package/dist/controllers/action-metadata.controller.js +1 -1
- package/dist/controllers/agent-event.controller.d.ts +1 -1
- package/dist/controllers/agent-event.controller.js +1 -1
- package/dist/controllers/agent-session.controller.d.ts +1 -1
- package/dist/controllers/agent-session.controller.js +1 -1
- package/dist/controllers/authentication.controller.d.ts +1 -1
- package/dist/controllers/authentication.controller.d.ts.map +1 -1
- package/dist/controllers/authentication.controller.js +4 -3
- package/dist/controllers/authentication.controller.js.map +1 -1
- package/dist/controllers/chatter-message.controller.d.ts +5 -0
- package/dist/controllers/chatter-message.controller.d.ts.map +1 -1
- package/dist/controllers/chatter-message.controller.js +14 -0
- package/dist/controllers/chatter-message.controller.js.map +1 -1
- package/dist/controllers/dashboard-user-layout.controller.d.ts +1 -1
- package/dist/controllers/dashboard-user-layout.controller.js +1 -1
- package/dist/controllers/email-template.controller.d.ts +1 -1
- package/dist/controllers/email-template.controller.js +1 -1
- package/dist/controllers/export-template.controller.d.ts +1 -1
- package/dist/controllers/export-template.controller.d.ts.map +1 -1
- package/dist/controllers/export-template.controller.js +6 -4
- package/dist/controllers/export-template.controller.js.map +1 -1
- package/dist/controllers/export-transaction.controller.d.ts +1 -1
- package/dist/controllers/export-transaction.controller.js +1 -1
- package/dist/controllers/field-metadata.controller.d.ts +2 -2
- package/dist/controllers/import-transaction-error-log.controller.d.ts +1 -1
- package/dist/controllers/import-transaction-error-log.controller.js +1 -1
- package/dist/controllers/import-transaction.controller.d.ts +1 -1
- package/dist/controllers/import-transaction.controller.d.ts.map +1 -1
- package/dist/controllers/import-transaction.controller.js +7 -7
- package/dist/controllers/import-transaction.controller.js.map +1 -1
- package/dist/controllers/list-of-values.controller.d.ts +1 -1
- package/dist/controllers/list-of-values.controller.js +1 -1
- package/dist/controllers/locale.controller.d.ts +1 -1
- package/dist/controllers/locale.controller.js +1 -1
- package/dist/controllers/mcp-audit-log.controller.d.ts +1 -1
- package/dist/controllers/mcp-audit-log.controller.js +1 -1
- package/dist/controllers/media.controller.d.ts +2 -2
- package/dist/controllers/media.controller.d.ts.map +1 -1
- package/dist/controllers/media.controller.js +13 -8
- package/dist/controllers/media.controller.js.map +1 -1
- package/dist/controllers/menu-item-metadata.controller.d.ts +1 -1
- package/dist/controllers/menu-item-metadata.controller.js +1 -1
- package/dist/controllers/model-sequence.controller.d.ts +1 -1
- package/dist/controllers/model-sequence.controller.js +1 -1
- package/dist/controllers/module-package.controller.d.ts.map +1 -1
- package/dist/controllers/module-package.controller.js +2 -3
- package/dist/controllers/module-package.controller.js.map +1 -1
- package/dist/controllers/mpin-authentication.controller.d.ts +44 -0
- package/dist/controllers/mpin-authentication.controller.d.ts.map +1 -0
- package/dist/controllers/mpin-authentication.controller.js +102 -0
- package/dist/controllers/mpin-authentication.controller.js.map +1 -0
- package/dist/controllers/mq-message-queue.controller.d.ts +1 -1
- package/dist/controllers/mq-message-queue.controller.js +1 -1
- package/dist/controllers/mq-message.controller.d.ts +1 -1
- package/dist/controllers/mq-message.controller.js +1 -1
- package/dist/controllers/permission-metadata.controller.d.ts +1 -1
- package/dist/controllers/permission-metadata.controller.js +1 -1
- package/dist/controllers/role-metadata.controller.d.ts +1 -1
- package/dist/controllers/role-metadata.controller.js +1 -1
- package/dist/controllers/saved-filters.controller.d.ts +1 -1
- package/dist/controllers/saved-filters.controller.js +1 -1
- package/dist/controllers/scheduled-job.controller.d.ts +1 -1
- package/dist/controllers/scheduled-job.controller.js +1 -1
- package/dist/controllers/security-rule.controller.d.ts +1 -1
- package/dist/controllers/security-rule.controller.js +1 -1
- package/dist/controllers/sms-template.controller.d.ts +1 -1
- package/dist/controllers/sms-template.controller.js +1 -1
- package/dist/controllers/user-activity-history.controller.d.ts +1 -1
- package/dist/controllers/user-activity-history.controller.js +1 -1
- package/dist/controllers/user-view-metadata.controller.d.ts +1 -1
- package/dist/controllers/user-view-metadata.controller.js +1 -1
- package/dist/controllers/user.controller.d.ts +2 -2
- package/dist/controllers/user.controller.js +2 -2
- package/dist/controllers/view-metadata.controller.d.ts +2 -2
- package/dist/controllers/view-metadata.controller.js +1 -1
- package/dist/controllers/workflow-definition.controller.d.ts +1 -1
- package/dist/controllers/workflow-definition.controller.js +1 -1
- package/dist/controllers/workflow-execution-artifact.controller.d.ts +1 -1
- package/dist/controllers/workflow-execution-artifact.controller.js +1 -1
- package/dist/controllers/workflow-execution-log.controller.d.ts +1 -1
- package/dist/controllers/workflow-execution-log.controller.js +1 -1
- package/dist/controllers/workflow-execution.controller.d.ts +1 -1
- package/dist/controllers/workflow-execution.controller.js +1 -1
- package/dist/controllers/workflow-secret.controller.d.ts +1 -1
- package/dist/controllers/workflow-secret.controller.js +1 -1
- package/dist/controllers/workflow-step-execution.controller.d.ts +1 -1
- package/dist/controllers/workflow-step-execution.controller.js +1 -1
- package/dist/controllers/workflow-trigger-execution.controller.d.ts +1 -1
- package/dist/controllers/workflow-trigger-execution.controller.js +1 -1
- package/dist/dtos/basic-filters.dto.d.ts +0 -1
- package/dist/dtos/basic-filters.dto.d.ts.map +1 -1
- package/dist/dtos/basic-filters.dto.js +1 -6
- package/dist/dtos/basic-filters.dto.js.map +1 -1
- package/dist/dtos/change-mpin.dto.d.ts +6 -0
- package/dist/dtos/change-mpin.dto.d.ts.map +1 -0
- package/dist/dtos/change-mpin.dto.js +39 -0
- package/dist/dtos/change-mpin.dto.js.map +1 -0
- package/dist/dtos/create-field-metadata.dto.d.ts +3 -6
- package/dist/dtos/create-field-metadata.dto.d.ts.map +1 -1
- package/dist/dtos/create-field-metadata.dto.js +15 -10
- package/dist/dtos/create-field-metadata.dto.js.map +1 -1
- package/dist/dtos/create-model-sequence.dto.d.ts +1 -1
- package/dist/dtos/create-model-sequence.dto.d.ts.map +1 -1
- package/dist/dtos/create-model-sequence.dto.js +1 -1
- package/dist/dtos/create-model-sequence.dto.js.map +1 -1
- package/dist/dtos/mpin-login.dto.d.ts +5 -0
- package/dist/dtos/mpin-login.dto.d.ts.map +1 -0
- package/dist/dtos/mpin-login.dto.js +33 -0
- package/dist/dtos/mpin-login.dto.js.map +1 -0
- package/dist/dtos/setup-mpin.dto.d.ts +7 -0
- package/dist/dtos/setup-mpin.dto.d.ts.map +1 -0
- package/dist/dtos/setup-mpin.dto.js +47 -0
- package/dist/dtos/setup-mpin.dto.js.map +1 -0
- package/dist/entities/common.entity.d.ts +4 -0
- package/dist/entities/common.entity.d.ts.map +1 -1
- package/dist/entities/common.entity.js +25 -1
- package/dist/entities/common.entity.js.map +1 -1
- package/dist/entities/dashboard-user-layout.entity.js +2 -2
- package/dist/entities/dashboard-user-layout.entity.js.map +1 -1
- package/dist/entities/field-metadata.entity.d.ts +1 -0
- package/dist/entities/field-metadata.entity.d.ts.map +1 -1
- package/dist/entities/field-metadata.entity.js +5 -1
- package/dist/entities/field-metadata.entity.js.map +1 -1
- package/dist/entities/saved-filters.entity.js +3 -3
- package/dist/entities/saved-filters.entity.js.map +1 -1
- package/dist/entities/user-device-credential.entity.d.ts +18 -0
- package/dist/entities/user-device-credential.entity.d.ts.map +1 -0
- package/dist/entities/user-device-credential.entity.js +91 -0
- package/dist/entities/user-device-credential.entity.js.map +1 -0
- package/dist/entities/user.entity.d.ts.map +1 -1
- package/dist/entities/user.entity.js +36 -0
- package/dist/entities/user.entity.js.map +1 -1
- package/dist/entities/view-metadata.entity.js.map +1 -1
- package/dist/entities/workflow-execution-artifact.entity.d.ts.map +1 -1
- package/dist/entities/workflow-execution-artifact.entity.js +4 -3
- package/dist/entities/workflow-execution-artifact.entity.js.map +1 -1
- package/dist/entities/workflow-execution-log.entity.d.ts.map +1 -1
- package/dist/entities/workflow-execution-log.entity.js +4 -3
- package/dist/entities/workflow-execution-log.entity.js.map +1 -1
- package/dist/entities/workflow-execution.entity.d.ts.map +1 -1
- package/dist/entities/workflow-execution.entity.js +3 -2
- package/dist/entities/workflow-execution.entity.js.map +1 -1
- package/dist/entities/workflow-secret.entity.d.ts.map +1 -1
- package/dist/entities/workflow-secret.entity.js +3 -2
- package/dist/entities/workflow-secret.entity.js.map +1 -1
- package/dist/entities/workflow-step-execution.entity.d.ts.map +1 -1
- package/dist/entities/workflow-step-execution.entity.js +3 -2
- package/dist/entities/workflow-step-execution.entity.js.map +1 -1
- package/dist/entities/workflow-trigger-execution.entity.d.ts.map +1 -1
- package/dist/entities/workflow-trigger-execution.entity.js +7 -6
- package/dist/entities/workflow-trigger-execution.entity.js.map +1 -1
- package/dist/factories/mail.factory.d.ts.map +1 -1
- package/dist/factories/mail.factory.js +4 -0
- package/dist/factories/mail.factory.js.map +1 -1
- package/dist/filters/http-exception.filter.d.ts.map +1 -1
- package/dist/filters/http-exception.filter.js +5 -1
- package/dist/filters/http-exception.filter.js.map +1 -1
- package/dist/helpers/bootstrap.helper.d.ts +5 -2
- package/dist/helpers/bootstrap.helper.d.ts.map +1 -1
- package/dist/helpers/bootstrap.helper.js +7 -3
- package/dist/helpers/bootstrap.helper.js.map +1 -1
- package/dist/helpers/field-crud-managers/MediaFieldCrudManager.d.ts +7 -0
- package/dist/helpers/field-crud-managers/MediaFieldCrudManager.d.ts.map +1 -1
- package/dist/helpers/field-crud-managers/MediaFieldCrudManager.js +66 -32
- package/dist/helpers/field-crud-managers/MediaFieldCrudManager.js.map +1 -1
- package/dist/helpers/file-download.helper.d.ts +9 -0
- package/dist/helpers/file-download.helper.d.ts.map +1 -0
- package/dist/helpers/file-download.helper.js +19 -0
- package/dist/helpers/file-download.helper.js.map +1 -0
- package/dist/helpers/model-metadata-helper.service.d.ts.map +1 -1
- package/dist/helpers/model-metadata-helper.service.js +30 -1
- package/dist/helpers/model-metadata-helper.service.js.map +1 -1
- package/dist/helpers/security.helper.d.ts +5 -1
- package/dist/helpers/security.helper.d.ts.map +1 -1
- package/dist/helpers/security.helper.js +15 -4
- package/dist/helpers/security.helper.js.map +1 -1
- package/dist/helpers/solid-core-error-codes-provider.service.d.ts.map +1 -1
- package/dist/helpers/solid-core-error-codes-provider.service.js +45 -0
- package/dist/helpers/solid-core-error-codes-provider.service.js.map +1 -1
- package/dist/helpers/solid-microservice-adapter.service.d.ts.map +1 -1
- package/dist/helpers/solid-microservice-adapter.service.js +1 -1
- package/dist/helpers/solid-microservice-adapter.service.js.map +1 -1
- package/dist/helpers/solid-registry.js +1 -1
- package/dist/helpers/solid-registry.js.map +1 -1
- package/dist/helpers/typeorm-db-helper.d.ts.map +1 -1
- package/dist/helpers/typeorm-db-helper.js +9 -0
- package/dist/helpers/typeorm-db-helper.js.map +1 -1
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -1
- package/dist/interfaces/active-user-data.interface.d.ts +1 -0
- package/dist/interfaces/active-user-data.interface.d.ts.map +1 -1
- package/dist/interfaces/active-user-data.interface.js.map +1 -1
- package/dist/interfaces.d.ts +1 -0
- package/dist/interfaces.d.ts.map +1 -1
- package/dist/interfaces.js.map +1 -1
- package/dist/repository/user-device-credential.repository.d.ts +12 -0
- package/dist/repository/user-device-credential.repository.d.ts.map +1 -0
- package/dist/repository/user-device-credential.repository.js +34 -0
- package/dist/repository/user-device-credential.repository.js.map +1 -0
- package/dist/seeders/module-metadata-seeder.service.d.ts.map +1 -1
- package/dist/seeders/module-metadata-seeder.service.js +51 -30
- package/dist/seeders/module-metadata-seeder.service.js.map +1 -1
- package/dist/seeders/module-test-data.service.d.ts +3 -1
- package/dist/seeders/module-test-data.service.d.ts.map +1 -1
- package/dist/seeders/module-test-data.service.js +8 -2
- package/dist/seeders/module-test-data.service.js.map +1 -1
- package/dist/seeders/seed-data/solid-core-metadata.json +290 -78
- package/dist/services/api-key.service.d.ts.map +1 -1
- package/dist/services/api-key.service.js +1 -1
- package/dist/services/api-key.service.js.map +1 -1
- package/dist/services/authentication.service.d.ts +9 -5
- package/dist/services/authentication.service.d.ts.map +1 -1
- package/dist/services/authentication.service.js +102 -23
- package/dist/services/authentication.service.js.map +1 -1
- package/dist/services/chatter-message.service.d.ts +16 -1
- package/dist/services/chatter-message.service.d.ts.map +1 -1
- package/dist/services/chatter-message.service.js +100 -16
- package/dist/services/chatter-message.service.js.map +1 -1
- package/dist/services/crud-helper.service.d.ts +6 -4
- package/dist/services/crud-helper.service.d.ts.map +1 -1
- package/dist/services/crud-helper.service.js +32 -48
- package/dist/services/crud-helper.service.js.map +1 -1
- package/dist/services/crud.service.d.ts +13 -1
- package/dist/services/crud.service.d.ts.map +1 -1
- package/dist/services/crud.service.js +94 -68
- package/dist/services/crud.service.js.map +1 -1
- package/dist/services/datasource-introspection.service.d.ts.map +1 -1
- package/dist/services/datasource-introspection.service.js.map +1 -1
- package/dist/services/draft-publish-helper.service.d.ts +53 -0
- package/dist/services/draft-publish-helper.service.d.ts.map +1 -0
- package/dist/services/draft-publish-helper.service.js +402 -0
- package/dist/services/draft-publish-helper.service.js.map +1 -0
- package/dist/services/field-metadata.service.d.ts +2 -2
- package/dist/services/field-metadata.service.d.ts.map +1 -1
- package/dist/services/field-metadata.service.js +4 -1
- package/dist/services/field-metadata.service.js.map +1 -1
- package/dist/services/internationalisation-helper.service.d.ts +19 -0
- package/dist/services/internationalisation-helper.service.d.ts.map +1 -0
- package/dist/services/internationalisation-helper.service.js +107 -0
- package/dist/services/internationalisation-helper.service.js.map +1 -0
- package/dist/services/locale.service.d.ts +1 -1
- package/dist/services/media-storage.utils.d.ts +1 -0
- package/dist/services/media-storage.utils.d.ts.map +1 -1
- package/dist/services/media-storage.utils.js +12 -1
- package/dist/services/media-storage.utils.js.map +1 -1
- package/dist/services/media.service.d.ts +3 -2
- package/dist/services/media.service.d.ts.map +1 -1
- package/dist/services/media.service.js +45 -29
- package/dist/services/media.service.js.map +1 -1
- package/dist/services/metadata-validation.service.d.ts +7 -0
- package/dist/services/metadata-validation.service.d.ts.map +1 -0
- package/dist/services/metadata-validation.service.js +42 -0
- package/dist/services/metadata-validation.service.js.map +1 -0
- package/dist/services/model-metadata.service.d.ts.map +1 -1
- package/dist/services/model-metadata.service.js +2 -1
- package/dist/services/model-metadata.service.js.map +1 -1
- package/dist/services/module-metadata.service.d.ts.map +1 -1
- package/dist/services/module-metadata.service.js +9 -1
- package/dist/services/module-metadata.service.js.map +1 -1
- package/dist/services/mpin.service.d.ts +67 -0
- package/dist/services/mpin.service.d.ts.map +1 -0
- package/dist/services/mpin.service.js +282 -0
- package/dist/services/mpin.service.js.map +1 -0
- package/dist/services/object.utils.d.ts +2 -0
- package/dist/services/object.utils.d.ts.map +1 -0
- package/dist/services/object.utils.js +11 -0
- package/dist/services/object.utils.js.map +1 -0
- package/dist/services/refresh-token-ids-storage.service.d.ts +25 -6
- package/dist/services/refresh-token-ids-storage.service.d.ts.map +1 -1
- package/dist/services/refresh-token-ids-storage.service.js +80 -42
- package/dist/services/refresh-token-ids-storage.service.js.map +1 -1
- package/dist/services/setting.service.d.ts.map +1 -1
- package/dist/services/setting.service.js +6 -1
- package/dist/services/setting.service.js.map +1 -1
- package/dist/services/settings/default-settings-provider.service.d.ts +248 -12
- package/dist/services/settings/default-settings-provider.service.d.ts.map +1 -1
- package/dist/services/settings/default-settings-provider.service.js +143 -6
- package/dist/services/settings/default-settings-provider.service.js.map +1 -1
- package/dist/services/user.service.d.ts +2 -2
- package/dist/services/user.service.d.ts.map +1 -1
- package/dist/services/user.service.js +9 -3
- package/dist/services/user.service.js.map +1 -1
- package/dist/services/view-metadata.service.d.ts +1 -2
- package/dist/services/view-metadata.service.d.ts.map +1 -1
- package/dist/services/view-metadata.service.js +3 -55
- package/dist/services/view-metadata.service.js.map +1 -1
- package/dist/services/workflow/nodes/execution-fail.node.d.ts +6 -0
- package/dist/services/workflow/nodes/execution-fail.node.d.ts.map +1 -0
- package/dist/services/workflow/nodes/execution-fail.node.js +81 -0
- package/dist/services/workflow/nodes/execution-fail.node.js.map +1 -0
- package/dist/services/workflow/nodes/for-each.node.d.ts +2 -0
- package/dist/services/workflow/nodes/for-each.node.d.ts.map +1 -1
- package/dist/services/workflow/nodes/for-each.node.js +114 -5
- package/dist/services/workflow/nodes/for-each.node.js.map +1 -1
- package/dist/services/workflow/nodes/if.node.d.ts.map +1 -1
- package/dist/services/workflow/nodes/if.node.js +7 -0
- package/dist/services/workflow/nodes/if.node.js.map +1 -1
- package/dist/services/workflow/nodes/log-write.node.d.ts.map +1 -1
- package/dist/services/workflow/nodes/log-write.node.js +2 -0
- package/dist/services/workflow/nodes/log-write.node.js.map +1 -1
- package/dist/services/workflow/nodes/loop-until.node.d.ts +12 -0
- package/dist/services/workflow/nodes/loop-until.node.d.ts.map +1 -0
- package/dist/services/workflow/nodes/loop-until.node.js +281 -0
- package/dist/services/workflow/nodes/loop-until.node.js.map +1 -0
- package/dist/services/workflow/nodes/parallel.node.d.ts.map +1 -1
- package/dist/services/workflow/nodes/parallel.node.js +7 -0
- package/dist/services/workflow/nodes/parallel.node.js.map +1 -1
- package/dist/services/workflow/nodes/sequential.node.d.ts.map +1 -1
- package/dist/services/workflow/nodes/sequential.node.js +7 -0
- package/dist/services/workflow/nodes/sequential.node.js.map +1 -1
- package/dist/services/workflow/nodes/switch.node.d.ts.map +1 -1
- package/dist/services/workflow/nodes/switch.node.js +7 -0
- package/dist/services/workflow/nodes/switch.node.js.map +1 -1
- package/dist/services/workflow/workflow-definition-validator.service.d.ts.map +1 -1
- package/dist/services/workflow/workflow-definition-validator.service.js +5 -2
- package/dist/services/workflow/workflow-definition-validator.service.js.map +1 -1
- package/dist/services/workflow/workflow-expression.service.d.ts.map +1 -1
- package/dist/services/workflow/workflow-expression.service.js +5 -0
- package/dist/services/workflow/workflow-expression.service.js.map +1 -1
- package/dist/services/workflow/workflow-node-registry.service.d.ts +2 -1
- package/dist/services/workflow/workflow-node-registry.service.d.ts.map +1 -1
- package/dist/services/workflow/workflow-node-registry.service.js +7 -0
- package/dist/services/workflow/workflow-node-registry.service.js.map +1 -1
- package/dist/services/workflow/workflow-runtime.service.d.ts +8 -0
- package/dist/services/workflow/workflow-runtime.service.d.ts.map +1 -1
- package/dist/services/workflow/workflow-runtime.service.js +197 -32
- package/dist/services/workflow/workflow-runtime.service.js.map +1 -1
- package/dist/services/workflow-definition.service.d.ts +1 -1
- package/dist/solid-core.module.d.ts +1 -3
- package/dist/solid-core.module.d.ts.map +1 -1
- package/dist/solid-core.module.js +28 -40
- package/dist/solid-core.module.js.map +1 -1
- package/dist/testing/adapters/ui/playwright-adapter.d.ts +5 -0
- package/dist/testing/adapters/ui/playwright-adapter.d.ts.map +1 -1
- package/dist/testing/adapters/ui/playwright-adapter.js +17 -1
- package/dist/testing/adapters/ui/playwright-adapter.js.map +1 -1
- package/dist/testing/adapters/ui/ui.types.d.ts +2 -0
- package/dist/testing/adapters/ui/ui.types.d.ts.map +1 -1
- package/dist/testing/adapters/ui/ui.types.js.map +1 -1
- package/dist/testing/reporter/console-reporter.d.ts +3 -0
- package/dist/testing/reporter/console-reporter.d.ts.map +1 -1
- package/dist/testing/reporter/console-reporter.js +2 -0
- package/dist/testing/reporter/console-reporter.js.map +1 -1
- package/dist/testing/reporter/progress-reporter.d.ts +64 -0
- package/dist/testing/reporter/progress-reporter.d.ts.map +1 -0
- package/dist/testing/reporter/progress-reporter.js +224 -0
- package/dist/testing/reporter/progress-reporter.js.map +1 -0
- package/dist/testing/reporter/reporter.types.d.ts +3 -0
- package/dist/testing/reporter/reporter.types.d.ts.map +1 -1
- package/dist/testing/reporter/reporter.types.js.map +1 -1
- package/dist/testing/runner/run-from-metadata.d.ts.map +1 -1
- package/dist/testing/runner/run-from-metadata.js +1 -0
- package/dist/testing/runner/run-from-metadata.js.map +1 -1
- package/dist/testing/steps/ui/actions.step.d.ts.map +1 -1
- package/dist/testing/steps/ui/actions.step.js +6 -2
- package/dist/testing/steps/ui/actions.step.js.map +1 -1
- package/dist/testing/steps/ui/assertions.step.d.ts.map +1 -1
- package/dist/testing/steps/ui/assertions.step.js +11 -3
- package/dist/testing/steps/ui/assertions.step.js.map +1 -1
- package/dist/testing/steps/ui/form.step.d.ts.map +1 -1
- package/dist/testing/steps/ui/form.step.js +9 -3
- package/dist/testing/steps/ui/form.step.js.map +1 -1
- package/dist/testing/steps/ui/manual.step.js +1 -1
- package/dist/testing/steps/ui/manual.step.js.map +1 -1
- package/dist/testing/steps/ui/navigation.step.d.ts.map +1 -1
- package/dist/testing/steps/ui/navigation.step.js +3 -1
- package/dist/testing/steps/ui/navigation.step.js.map +1 -1
- package/dist/theme/theme-registry.d.ts +14 -0
- package/dist/theme/theme-registry.d.ts.map +1 -0
- package/dist/theme/theme-registry.js +147 -0
- package/dist/theme/theme-registry.js.map +1 -0
- package/dist/types/workflow-dsl.types.d.ts +14 -0
- package/dist/types/workflow-dsl.types.d.ts.map +1 -1
- package/dist/types/workflow-dsl.types.js.map +1 -1
- package/package.json +2 -2
- package/src/commands/run-tests.command.ts +64 -4
- package/src/commands/seed.command.ts +19 -0
- package/src/config/cache.options.ts +9 -1
- package/src/constants/chatter-message.constants.ts +12 -0
- package/src/constants/draft-publish-fields.ts +5 -0
- package/src/constants/error-messages.ts +14 -0
- package/src/constants/media-file-types.ts +128 -0
- package/src/constants/success-messages.ts +5 -0
- package/src/constants/user.constants.ts +13 -0
- package/src/controllers/authentication.controller.ts +5 -2
- package/src/controllers/chatter-message.controller.ts +8 -0
- package/src/controllers/export-template.controller.ts +5 -3
- package/src/controllers/import-transaction.controller.ts +6 -6
- package/src/controllers/media.controller.ts +17 -6
- package/src/controllers/module-package.controller.ts +2 -3
- package/src/controllers/mpin-authentication.controller.ts +67 -0
- package/src/dtos/basic-filters.dto.ts +0 -4
- package/src/dtos/change-mpin.dto.ts +18 -0
- package/src/dtos/create-field-metadata.dto.ts +17 -9
- package/src/dtos/create-model-sequence.dto.ts +1 -1
- package/src/dtos/mpin-login.dto.ts +24 -0
- package/src/dtos/setup-mpin.dto.ts +51 -0
- package/src/entities/common.entity.ts +24 -0
- package/src/entities/dashboard-user-layout.entity.ts +2 -2
- package/src/entities/field-metadata.entity.ts +3 -0
- package/src/entities/saved-filters.entity.ts +3 -3
- package/src/entities/user-device-credential.entity.ts +130 -0
- package/src/entities/user.entity.ts +53 -36
- package/src/entities/view-metadata.entity.ts +2 -2
- package/src/entities/workflow-execution-artifact.entity.ts +4 -3
- package/src/entities/workflow-execution-log.entity.ts +4 -3
- package/src/entities/workflow-execution.entity.ts +3 -2
- package/src/entities/workflow-secret.entity.ts +3 -2
- package/src/entities/workflow-step-execution.entity.ts +3 -2
- package/src/entities/workflow-trigger-execution.entity.ts +7 -6
- package/src/factories/mail.factory.ts +7 -1
- package/src/filters/http-exception.filter.ts +11 -1
- package/src/helpers/bootstrap.helper.ts +43 -6
- package/src/helpers/field-crud-managers/MediaFieldCrudManager.ts +90 -37
- package/src/helpers/file-download.helper.ts +45 -0
- package/src/helpers/model-metadata-helper.service.ts +32 -1
- package/src/helpers/security.helper.ts +35 -8
- package/src/helpers/solid-core-error-codes-provider.service.ts +53 -0
- package/src/helpers/solid-microservice-adapter.service.ts +6 -1
- package/src/helpers/solid-registry.ts +1 -1
- package/src/helpers/typeorm-db-helper.ts +12 -1
- package/src/index.ts +10 -0
- package/src/interfaces/active-user-data.interface.ts +9 -0
- package/src/interfaces.ts +1 -0
- package/src/repository/user-device-credential.repository.ts +17 -0
- package/src/seeders/module-metadata-seeder.service.ts +61 -39
- package/src/seeders/module-test-data.service.ts +6 -0
- package/src/seeders/seed-data/solid-core-metadata.json +290 -78
- package/src/services/api-key.service.ts +13 -1
- package/src/services/authentication.service.ts +203 -41
- package/src/services/chatter-message.service.ts +180 -19
- package/src/services/crud-helper.service.ts +35 -50
- package/src/services/crud.service.ts +132 -105
- package/src/services/datasource-introspection.service.ts +5 -0
- package/src/services/draft-publish-helper.service.ts +581 -0
- package/src/services/field-metadata.service.ts +5 -2
- package/src/services/internationalisation-helper.service.ts +148 -0
- package/src/services/media-storage.utils.ts +26 -1
- package/src/services/media.service.ts +68 -36
- package/src/services/metadata-validation.service.ts +39 -0
- package/src/services/model-metadata.service.ts +4 -1
- package/src/services/module-metadata.service.ts +10 -1
- package/src/services/mpin.service.ts +447 -0
- package/src/services/object.utils.ts +10 -0
- package/src/services/refresh-token-ids-storage.service.ts +229 -90
- package/src/services/setting.service.ts +8 -1
- package/src/services/settings/default-settings-provider.service.ts +154 -6
- package/src/services/user.service.ts +18 -3
- package/src/services/view-metadata.service.ts +5 -145
- package/src/services/workflow/nodes/execution-fail.node.ts +82 -0
- package/src/services/workflow/nodes/for-each.node.ts +140 -6
- package/src/services/workflow/nodes/if.node.ts +7 -0
- package/src/services/workflow/nodes/log-write.node.ts +2 -0
- package/src/services/workflow/nodes/loop-until.node.ts +343 -0
- package/src/services/workflow/nodes/parallel.node.ts +7 -0
- package/src/services/workflow/nodes/sequential.node.ts +7 -0
- package/src/services/workflow/nodes/switch.node.ts +7 -0
- package/src/services/workflow/workflow-definition-validator.service.ts +5 -2
- package/src/services/workflow/workflow-expression.service.ts +5 -0
- package/src/services/workflow/workflow-node-registry.service.ts +11 -0
- package/src/services/workflow/workflow-runtime.service.ts +274 -39
- package/src/solid-core.module.ts +46 -15
- package/src/testing/README.md +75 -3
- package/src/testing/adapters/ui/playwright-adapter.ts +25 -0
- package/src/testing/adapters/ui/ui.types.ts +2 -0
- package/src/testing/reporter/console-reporter.ts +4 -0
- package/src/testing/reporter/progress-reporter.ts +251 -0
- package/src/testing/reporter/reporter.types.ts +3 -0
- package/src/testing/runner/run-from-metadata.ts +1 -0
- package/src/testing/steps/ui/actions.step.ts +8 -4
- package/src/testing/steps/ui/assertions.step.ts +18 -5
- package/src/testing/steps/ui/form.step.ts +16 -6
- package/src/testing/steps/ui/manual.step.ts +1 -1
- package/src/testing/steps/ui/navigation.step.ts +4 -2
- package/src/theme/theme-registry.ts +181 -0
- package/src/types/workflow-dsl.types.ts +43 -0
package/src/testing/README.md
CHANGED
|
@@ -75,6 +75,57 @@ General step fields:
|
|
|
75
75
|
- `timeoutMs` (optional): per-step timeout override
|
|
76
76
|
- `spec` (optional): used by `test.spec` to identify the spec
|
|
77
77
|
|
|
78
|
+
## Timeouts
|
|
79
|
+
There are two independent timeout layers. They are easy to confuse, so note which one you want:
|
|
80
|
+
|
|
81
|
+
**1. Engine timeouts** — `scenario.timeoutMs` and the top-level `step.timeoutMs`.
|
|
82
|
+
These wrap execution in a `Promise.race` (`core/timeout.ts`). They are a hard upper bound
|
|
83
|
+
on wall-clock time and do **not** cancel the underlying browser call, so the failure message
|
|
84
|
+
only tells you the scenario or op that overran.
|
|
85
|
+
|
|
86
|
+
**2. UI (Playwright) timeouts** — the run-wide default plus per-step `with.timeoutMs`.
|
|
87
|
+
This is what governs how long `ui.expectVisible`, `ui.click`, `ui.fill` etc. wait for a
|
|
88
|
+
selector. Playwright cancels the operation itself, so the error names the selector and the
|
|
89
|
+
state it was waiting for. **If your UI steps are timing out, this is the knob to turn.**
|
|
90
|
+
|
|
91
|
+
Resolution order for UI steps: `with.timeoutMs` → `--ui-timeout-ms` → `UI_TIMEOUT_MS` →
|
|
92
|
+
`uiTestDefaultTimeoutMs` setting → `30000`.
|
|
93
|
+
`ui.goto` uses the navigation timeout instead: `with.timeoutMs` → `--ui-navigation-timeout-ms`
|
|
94
|
+
→ `UI_NAVIGATION_TIMEOUT_MS` → `uiTestNavigationTimeoutMs` setting → the resolved UI timeout.
|
|
95
|
+
|
|
96
|
+
Raise the default for a whole run:
|
|
97
|
+
```bash
|
|
98
|
+
solid test run --module <module-name> --ui-timeout-ms 60000
|
|
99
|
+
# or
|
|
100
|
+
UI_TIMEOUT_MS=60000 solid test run --module <module-name>
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Or set the installation-wide default under **Settings → Testing Settings** in the admin UI
|
|
104
|
+
(`uiTestDefaultTimeoutMs` / `uiTestNavigationTimeoutMs`). Those rows are created by `solid seed`;
|
|
105
|
+
until then the built-in `30000` applies. Flags and env vars still win, so CI keeps per-run control.
|
|
106
|
+
|
|
107
|
+
The seeded value of those two settings can be provisioned from the environment with
|
|
108
|
+
`COMMON_UI_TEST_DEFAULT_TIMEOUT_MS` and `COMMON_UI_TEST_NAVIGATION_TIMEOUT_MS` (the latter falls
|
|
109
|
+
back to the former). Seeding is insert-only, so these apply on first seed only — afterwards the
|
|
110
|
+
stored value wins and the setting must be changed in the admin UI. Values that are missing,
|
|
111
|
+
non-numeric, or not positive fall back to `30000`.
|
|
112
|
+
|
|
113
|
+
Note these are distinct from the run-time `UI_TIMEOUT_MS` / `UI_NAVIGATION_TIMEOUT_MS` vars,
|
|
114
|
+
which override the setting on a per-run basis and are read every run.
|
|
115
|
+
|
|
116
|
+
Or bump only the one slow step, leaving the rest of the suite strict:
|
|
117
|
+
```json
|
|
118
|
+
{
|
|
119
|
+
"then": {
|
|
120
|
+
"op": "ui.expectVisible",
|
|
121
|
+
"with": { "selector": "#report-grid", "timeoutMs": 90000 }
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
Caution: a scenario-level `timeoutMs` lower than the UI timeout will fire first and mask the
|
|
127
|
+
more useful Playwright error. Keep `defaults.timeoutMs` above your UI timeout.
|
|
128
|
+
|
|
78
129
|
## Interpolation
|
|
79
130
|
Available tokens:
|
|
80
131
|
- `${env:NAME}` (environment variables)
|
|
@@ -198,6 +249,7 @@ Description: Navigates the browser to a URL.
|
|
|
198
249
|
|
|
199
250
|
Options in `with`:
|
|
200
251
|
- `url` (required)
|
|
252
|
+
- `timeoutMs` (optional, overrides the run-wide UI navigation timeout)
|
|
201
253
|
|
|
202
254
|
### **Op: `ui.expectUrl`**
|
|
203
255
|
Description: Asserts the current page URL.
|
|
@@ -212,6 +264,7 @@ Description: Fills an input or editable element.
|
|
|
212
264
|
Options in `with`:
|
|
213
265
|
- `selector` (required)
|
|
214
266
|
- `value` (required)
|
|
267
|
+
- `timeoutMs` (optional, overrides the run-wide UI timeout)
|
|
215
268
|
|
|
216
269
|
### **Op: `ui.select`**
|
|
217
270
|
Description: Selects an option in a select element.
|
|
@@ -219,12 +272,14 @@ Description: Selects an option in a select element.
|
|
|
219
272
|
Options in `with`:
|
|
220
273
|
- `selector` (required)
|
|
221
274
|
- `value` (required)
|
|
275
|
+
- `timeoutMs` (optional, overrides the run-wide UI timeout)
|
|
222
276
|
|
|
223
277
|
### **Op: `ui.click`**
|
|
224
278
|
Description: Clicks an element located by selector.
|
|
225
279
|
|
|
226
280
|
Options in `with`:
|
|
227
281
|
- `selector` (required)
|
|
282
|
+
- `timeoutMs` (optional, overrides the run-wide UI timeout)
|
|
228
283
|
|
|
229
284
|
### **Op: `ui.press`**
|
|
230
285
|
Description: Presses a keyboard key on a focused element.
|
|
@@ -232,6 +287,7 @@ Description: Presses a keyboard key on a focused element.
|
|
|
232
287
|
Options in `with`:
|
|
233
288
|
- `selector` (required)
|
|
234
289
|
- `key` (required)
|
|
290
|
+
- `timeoutMs` (optional, overrides the run-wide UI timeout)
|
|
235
291
|
|
|
236
292
|
### **Op: `ui.waitForManual`**
|
|
237
293
|
Description: Pauses a headed Playwright run so a human can interact with the live browser, then resumes when Enter is pressed in the terminal.
|
|
@@ -242,7 +298,7 @@ Options in `with`:
|
|
|
242
298
|
- `waitForSelector` (optional, waits for a visible selector after resume)
|
|
243
299
|
- `waitForUrlEquals` (optional, waits until the current URL exactly matches)
|
|
244
300
|
- `waitForUrlContains` (optional, waits until the current URL contains a substring)
|
|
245
|
-
- `timeoutMs` (optional, timeout for post-resume waits)
|
|
301
|
+
- `timeoutMs` (optional, timeout for post-resume waits; defaults to the run-wide UI timeout)
|
|
246
302
|
- `bringToFront` (optional, defaults to `true`)
|
|
247
303
|
|
|
248
304
|
Notes:
|
|
@@ -269,6 +325,7 @@ Description: Waits for an element to be visible.
|
|
|
269
325
|
|
|
270
326
|
Options in `with`:
|
|
271
327
|
- `selector` (required)
|
|
328
|
+
- `timeoutMs` (optional, overrides the run-wide UI timeout)
|
|
272
329
|
|
|
273
330
|
### **Op: `ui.expectText`**
|
|
274
331
|
Description: Asserts the text content of an element.
|
|
@@ -277,6 +334,7 @@ Options in `with`:
|
|
|
277
334
|
- `selector` (required)
|
|
278
335
|
- `equals` (optional)
|
|
279
336
|
- `contains` (optional)
|
|
337
|
+
- `timeoutMs` (optional, overrides the run-wide UI timeout)
|
|
280
338
|
|
|
281
339
|
### **Op: `assert.equals`**
|
|
282
340
|
Description: Asserts strict equality between two values.
|
|
@@ -388,7 +446,12 @@ await runFromMetadata({
|
|
|
388
446
|
includeTags: ["smoke"],
|
|
389
447
|
defaults: { timeoutMs: 30_000, retries: 1 },
|
|
390
448
|
api: { baseUrl: "https://api.example.com" },
|
|
391
|
-
ui: {
|
|
449
|
+
ui: {
|
|
450
|
+
baseUrl: "https://app.example.com",
|
|
451
|
+
headless: true,
|
|
452
|
+
defaultTimeoutMs: 30_000,
|
|
453
|
+
navigationTimeoutMs: 45_000
|
|
454
|
+
}
|
|
392
455
|
});
|
|
393
456
|
```
|
|
394
457
|
|
|
@@ -409,9 +472,18 @@ Lightweight existing-database workflow:
|
|
|
409
472
|
|
|
410
473
|
For human-assisted OTP or third-party verification flows, use `ui.waitForManual` in a headed run so the browser remains interactive while the scenario is paused.
|
|
411
474
|
|
|
475
|
+
Common `test run` flags (all pass through solidctl unchanged):
|
|
476
|
+
- `--ui-base-url <url>` / `--api-base-url <url>`
|
|
477
|
+
- `--headless [true|false]`
|
|
478
|
+
- `--ui-timeout-ms <number>` — default wait for every UI step (see [Timeouts](#timeouts))
|
|
479
|
+
- `--ui-navigation-timeout-ms <number>` — default wait for `ui.goto`
|
|
480
|
+
- `--timeout-ms <number>` / `--retries <number>` — scenario-level guard and retry count
|
|
481
|
+
- `--scenario-ids <ids>` / `--include-tags <tags>` / `--skip-scenario-ids <ids>`
|
|
482
|
+
- `--no-progress` — disable the interactive test progress footer
|
|
483
|
+
|
|
412
484
|
## Add A New Step (SOP)
|
|
413
485
|
1. Create a new `*.step.ts` in the right domain folder.
|
|
414
486
|
2. Implement a `registerXSteps(registry)` function and `registry.register("op.name", handler)`.
|
|
415
487
|
3. Validate required `step.with` fields and throw clear errors.
|
|
416
488
|
4. Use adapters via `ctx.api` / `ctx.ui` and update `ctx.last` when helpful.
|
|
417
|
-
5. Export and register it from the domain `index.ts`.
|
|
489
|
+
5. Export and register it from the domain `index.ts`.
|
|
@@ -6,9 +6,13 @@ function isAbsoluteUrl(url: string): boolean {
|
|
|
6
6
|
return /^https?:\/\//i.test(url);
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
+
export const DEFAULT_UI_TIMEOUT_MS = 30_000;
|
|
10
|
+
|
|
9
11
|
export class PlaywrightAdapter {
|
|
10
12
|
private readonly baseUrl?: string;
|
|
11
13
|
private readonly headless: boolean;
|
|
14
|
+
private readonly defaultTimeoutMs: number;
|
|
15
|
+
private readonly navigationTimeoutMs: number;
|
|
12
16
|
private browser?: Browser;
|
|
13
17
|
private context?: BrowserContext;
|
|
14
18
|
public page?: Page;
|
|
@@ -16,16 +20,37 @@ export class PlaywrightAdapter {
|
|
|
16
20
|
constructor(opts?: PlaywrightAdapterOptions) {
|
|
17
21
|
this.baseUrl = opts?.baseUrl;
|
|
18
22
|
this.headless = opts?.headless ?? true;
|
|
23
|
+
this.defaultTimeoutMs = opts?.defaultTimeoutMs ?? DEFAULT_UI_TIMEOUT_MS;
|
|
24
|
+
this.navigationTimeoutMs =
|
|
25
|
+
opts?.navigationTimeoutMs ?? this.defaultTimeoutMs;
|
|
19
26
|
}
|
|
20
27
|
|
|
21
28
|
isHeadless(): boolean {
|
|
22
29
|
return this.headless;
|
|
23
30
|
}
|
|
24
31
|
|
|
32
|
+
/**
|
|
33
|
+
* Resolves the timeout for a single Playwright call: an explicit per-step
|
|
34
|
+
* value wins, otherwise the run-wide default applies.
|
|
35
|
+
*/
|
|
36
|
+
resolveTimeout(stepTimeoutMs?: number): number {
|
|
37
|
+
return typeof stepTimeoutMs === 'number' && Number.isFinite(stepTimeoutMs)
|
|
38
|
+
? stepTimeoutMs
|
|
39
|
+
: this.defaultTimeoutMs;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
resolveNavigationTimeout(stepTimeoutMs?: number): number {
|
|
43
|
+
return typeof stepTimeoutMs === 'number' && Number.isFinite(stepTimeoutMs)
|
|
44
|
+
? stepTimeoutMs
|
|
45
|
+
: this.navigationTimeoutMs;
|
|
46
|
+
}
|
|
47
|
+
|
|
25
48
|
async start(): Promise<void> {
|
|
26
49
|
const { chromium } = await import('playwright');
|
|
27
50
|
this.browser = await chromium.launch({ headless: this.headless });
|
|
28
51
|
this.context = await this.browser.newContext();
|
|
52
|
+
this.context.setDefaultTimeout(this.defaultTimeoutMs);
|
|
53
|
+
this.context.setDefaultNavigationTimeout(this.navigationTimeoutMs);
|
|
29
54
|
this.page = await this.context.newPage();
|
|
30
55
|
}
|
|
31
56
|
|
|
@@ -150,6 +150,10 @@ export class ConsoleReporter implements Reporter {
|
|
|
150
150
|
private passedScenarios = 0;
|
|
151
151
|
private failedScenarios = 0;
|
|
152
152
|
|
|
153
|
+
onRunStart(_args: { total: number }): void {
|
|
154
|
+
// Progress-aware reporters use this hook; the plain console reporter has no setup.
|
|
155
|
+
}
|
|
156
|
+
|
|
153
157
|
onScenarioStart(scenario: { id: string; name?: string }): void {
|
|
154
158
|
const label = scenario.name ? `${scenario.id} (${scenario.name})` : scenario.id;
|
|
155
159
|
console.log(`\n▶ Scenario: ${label}`);
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
import * as readline from "readline";
|
|
2
|
+
import type { StepPhase } from "../contracts/runtime-context.types";
|
|
3
|
+
import type { OpStep, ScenarioSpec } from "../contracts/testing-metadata.types";
|
|
4
|
+
import type { SolidTestSpecResult } from "../contracts/test-spec.types";
|
|
5
|
+
import type { Reporter } from "./reporter.types";
|
|
6
|
+
|
|
7
|
+
const ANSI_BOLD = "\u001b[1m";
|
|
8
|
+
const ANSI_BOLD_OFF = "\u001b[22m";
|
|
9
|
+
const ANSI_DIM = "\u001b[2m";
|
|
10
|
+
const ANSI_GREEN = "\u001b[32m";
|
|
11
|
+
const ANSI_COLOR_OFF = "\u001b[39m";
|
|
12
|
+
const ANSI_RED = "\u001b[31m";
|
|
13
|
+
const ANSI_INVERSE = "\u001b[7m";
|
|
14
|
+
const ANSI_INVERSE_OFF = "\u001b[27m";
|
|
15
|
+
|
|
16
|
+
export class ProgressReporter implements Reporter {
|
|
17
|
+
private startedAt = Date.now();
|
|
18
|
+
private total = 0;
|
|
19
|
+
private completed = 0;
|
|
20
|
+
private passed = 0;
|
|
21
|
+
private failed = 0;
|
|
22
|
+
private timer?: NodeJS.Timeout;
|
|
23
|
+
private rendered = false;
|
|
24
|
+
|
|
25
|
+
constructor(private readonly delegate: Reporter) {}
|
|
26
|
+
|
|
27
|
+
onRunStart(args: { total: number }): void {
|
|
28
|
+
this.total = args.total;
|
|
29
|
+
this.startedAt = Date.now();
|
|
30
|
+
this.completed = 0;
|
|
31
|
+
this.passed = 0;
|
|
32
|
+
this.failed = 0;
|
|
33
|
+
this.delegate.onRunStart?.(args);
|
|
34
|
+
this.startTimer();
|
|
35
|
+
this.renderFooter();
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
onScenarioStart(scenario: ScenarioSpec): void {
|
|
39
|
+
this.withFooterPaused(() => this.delegate.onScenarioStart(scenario));
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
onScenarioEnd(
|
|
43
|
+
scenario: ScenarioSpec,
|
|
44
|
+
result: { ok: boolean; error?: unknown; durationMs: number },
|
|
45
|
+
): void {
|
|
46
|
+
this.completed += 1;
|
|
47
|
+
if (result.ok) {
|
|
48
|
+
this.passed += 1;
|
|
49
|
+
} else {
|
|
50
|
+
this.failed += 1;
|
|
51
|
+
}
|
|
52
|
+
this.withFooterPaused(() => this.delegate.onScenarioEnd(scenario, result));
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
onStepStart(args: {
|
|
56
|
+
scenarioId: string;
|
|
57
|
+
phase: StepPhase;
|
|
58
|
+
step: OpStep;
|
|
59
|
+
}): void {
|
|
60
|
+
this.withFooterPaused(() => this.delegate.onStepStart(args));
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
onStepEnd(args: {
|
|
64
|
+
scenarioId: string;
|
|
65
|
+
phase: StepPhase;
|
|
66
|
+
step: OpStep;
|
|
67
|
+
ok: boolean;
|
|
68
|
+
error?: unknown;
|
|
69
|
+
durationMs: number;
|
|
70
|
+
}): void {
|
|
71
|
+
this.withFooterPaused(() => this.delegate.onStepEnd(args));
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
onSpecResult(args: {
|
|
75
|
+
scenarioId: string;
|
|
76
|
+
specId: string;
|
|
77
|
+
stepName?: string;
|
|
78
|
+
result: SolidTestSpecResult;
|
|
79
|
+
}): void {
|
|
80
|
+
this.withFooterPaused(() => this.delegate.onSpecResult?.(args));
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
attach(args: {
|
|
84
|
+
scenarioId: string;
|
|
85
|
+
name: string;
|
|
86
|
+
contentType: string;
|
|
87
|
+
data: Buffer | string;
|
|
88
|
+
}): void {
|
|
89
|
+
this.withFooterPaused(() => this.delegate.attach?.(args));
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
onRunEnd(args: {
|
|
93
|
+
ok: boolean;
|
|
94
|
+
total: number;
|
|
95
|
+
passed: number;
|
|
96
|
+
failed: number;
|
|
97
|
+
durationMs: number;
|
|
98
|
+
}): void {
|
|
99
|
+
this.completed = args.passed + args.failed;
|
|
100
|
+
this.passed = args.passed;
|
|
101
|
+
this.failed = args.failed;
|
|
102
|
+
this.total = args.total;
|
|
103
|
+
this.stopTimer();
|
|
104
|
+
this.withFooterPaused(() => this.delegate.onRunEnd?.(args), false);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
private startTimer(): void {
|
|
108
|
+
this.stopTimer();
|
|
109
|
+
if (!this.isInteractive()) {
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
this.timer = setInterval(() => this.renderFooter(), 1_000);
|
|
113
|
+
this.timer.unref?.();
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
private stopTimer(): void {
|
|
117
|
+
if (!this.timer) {
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
clearInterval(this.timer);
|
|
121
|
+
this.timer = undefined;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
private withFooterPaused(callback: () => void, renderAfter = true): void {
|
|
125
|
+
this.clearFooter();
|
|
126
|
+
callback();
|
|
127
|
+
if (renderAfter) {
|
|
128
|
+
this.renderFooter();
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
private renderFooter(): void {
|
|
133
|
+
if (!this.isInteractive()) {
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
const terminalWidth = process.stdout.columns || 80;
|
|
138
|
+
const elapsed = formatElapsed(Date.now() - this.startedAt);
|
|
139
|
+
const progressText = `${this.completed}/${this.total}`;
|
|
140
|
+
const resultText = `${ANSI_GREEN}${this.passed} passed${ANSI_COLOR_OFF}${ANSI_DIM} | ${ANSI_BOLD_OFF}${this.failed ? ANSI_RED : ANSI_DIM}${this.failed} failed${this.failed ? ANSI_COLOR_OFF : ANSI_BOLD_OFF}`;
|
|
141
|
+
const footer = [
|
|
142
|
+
`${ANSI_BOLD}Tests${ANSI_BOLD_OFF}: ${this.renderProgressBar(terminalWidth)} ${progressText}`,
|
|
143
|
+
`${ANSI_BOLD}Elapsed${ANSI_BOLD_OFF}: ${elapsed}`,
|
|
144
|
+
resultText,
|
|
145
|
+
].join(`${ANSI_DIM} | ${ANSI_BOLD_OFF}`);
|
|
146
|
+
|
|
147
|
+
readline.clearLine(process.stdout, 0);
|
|
148
|
+
readline.cursorTo(process.stdout, 0);
|
|
149
|
+
process.stdout.write(truncateAnsiText(`${ANSI_INVERSE} ${footer} ${ANSI_INVERSE_OFF}`, terminalWidth));
|
|
150
|
+
this.rendered = true;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
private clearFooter(): void {
|
|
154
|
+
if (!this.rendered || !this.isInteractive()) {
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
readline.clearLine(process.stdout, 0);
|
|
158
|
+
readline.cursorTo(process.stdout, 0);
|
|
159
|
+
this.rendered = false;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
private renderProgressBar(terminalWidth: number): string {
|
|
163
|
+
const width = terminalWidth >= 120 ? 30 : terminalWidth >= 90 ? 22 : 14;
|
|
164
|
+
const ratio = this.total > 0 ? Math.min(1, this.completed / this.total) : 0;
|
|
165
|
+
const filled = Math.round(width * ratio);
|
|
166
|
+
const empty = Math.max(0, width - filled);
|
|
167
|
+
return `[${ANSI_GREEN}${"=".repeat(filled)}${ANSI_COLOR_OFF}${" ".repeat(empty)}]`;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
private isInteractive(): boolean {
|
|
171
|
+
return Boolean(process.stdout.isTTY || process.env.SOLIDCTL_TEST_PROGRESS === "1");
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
function formatElapsed(durationMs: number): string {
|
|
176
|
+
const totalSeconds = Math.max(0, Math.floor(durationMs / 1000));
|
|
177
|
+
const minutes = Math.floor(totalSeconds / 60);
|
|
178
|
+
const seconds = totalSeconds % 60;
|
|
179
|
+
if (minutes < 60) {
|
|
180
|
+
return `${minutes}:${seconds.toString().padStart(2, "0")}`;
|
|
181
|
+
}
|
|
182
|
+
const hours = Math.floor(minutes / 60);
|
|
183
|
+
const remainingMinutes = minutes % 60;
|
|
184
|
+
return `${hours}:${remainingMinutes.toString().padStart(2, "0")}:${seconds.toString().padStart(2, "0")}`;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
function truncateAnsiText(text: string, maxWidth: number): string {
|
|
188
|
+
if (maxWidth <= 0) {
|
|
189
|
+
return "";
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
let visibleWidth = 0;
|
|
193
|
+
let index = 0;
|
|
194
|
+
let output = "";
|
|
195
|
+
let hasEscape = false;
|
|
196
|
+
|
|
197
|
+
while (index < text.length) {
|
|
198
|
+
if (text[index] === "\u001b") {
|
|
199
|
+
const match = /\u001b\[[0-9;]*m/.exec(text.slice(index));
|
|
200
|
+
if (!match) {
|
|
201
|
+
break;
|
|
202
|
+
}
|
|
203
|
+
output += match[0];
|
|
204
|
+
hasEscape = true;
|
|
205
|
+
index += match[0].length;
|
|
206
|
+
continue;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
if (visibleWidth >= maxWidth) {
|
|
210
|
+
break;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
output += text[index];
|
|
214
|
+
visibleWidth += 1;
|
|
215
|
+
index += 1;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
if (index < text.length && maxWidth >= 1) {
|
|
219
|
+
output = trimAnsiText(output, maxWidth - 1) + "…";
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
if (hasEscape && !output.endsWith(ANSI_INVERSE_OFF)) {
|
|
223
|
+
output += ANSI_INVERSE_OFF;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
return output;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
function trimAnsiText(text: string, maxWidth: number): string {
|
|
230
|
+
let visibleWidth = 0;
|
|
231
|
+
let index = 0;
|
|
232
|
+
let output = "";
|
|
233
|
+
|
|
234
|
+
while (index < text.length && visibleWidth < maxWidth) {
|
|
235
|
+
if (text[index] === "\u001b") {
|
|
236
|
+
const match = /\u001b\[[0-9;]*m/.exec(text.slice(index));
|
|
237
|
+
if (!match) {
|
|
238
|
+
break;
|
|
239
|
+
}
|
|
240
|
+
output += match[0];
|
|
241
|
+
index += match[0].length;
|
|
242
|
+
continue;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
output += text[index];
|
|
246
|
+
visibleWidth += 1;
|
|
247
|
+
index += 1;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
return output;
|
|
251
|
+
}
|
|
@@ -3,6 +3,9 @@ import type { OpStep, ScenarioSpec } from "../contracts/testing-metadata.types";
|
|
|
3
3
|
import type { SolidTestSpecResult } from "../contracts/test-spec.types";
|
|
4
4
|
|
|
5
5
|
export interface Reporter {
|
|
6
|
+
onRunStart?(args: {
|
|
7
|
+
total: number;
|
|
8
|
+
}): void;
|
|
6
9
|
onScenarioStart(scenario: ScenarioSpec): void;
|
|
7
10
|
onScenarioEnd(
|
|
8
11
|
scenario: ScenarioSpec,
|
|
@@ -67,6 +67,7 @@ export async function runFromMetadata(opts: RunnerOptions): Promise<void> {
|
|
|
67
67
|
|
|
68
68
|
const resources = new SimpleResourceStore();
|
|
69
69
|
const reporter = opts.reporter ?? new ConsoleReporter();
|
|
70
|
+
reporter.onRunStart?.({ total: scenarios.length });
|
|
70
71
|
const api = new ApiAdapter(opts.api);
|
|
71
72
|
const { PlaywrightAdapter } = await import("../adapters/ui/playwright-adapter");
|
|
72
73
|
const ui = new PlaywrightAdapter(opts.ui);
|
|
@@ -2,8 +2,8 @@ import type { TestContext } from "../../contracts/runtime-context.types";
|
|
|
2
2
|
import type { OpStep } from "../../contracts/testing-metadata.types";
|
|
3
3
|
import { StepRegistry } from "../../core/step-registry";
|
|
4
4
|
|
|
5
|
-
type ClickInput = { selector: string };
|
|
6
|
-
type PressInput = { selector: string; key: string };
|
|
5
|
+
type ClickInput = { selector: string; timeoutMs?: number };
|
|
6
|
+
type PressInput = { selector: string; key: string; timeoutMs?: number };
|
|
7
7
|
|
|
8
8
|
function requirePage(ctx: TestContext, op: string) {
|
|
9
9
|
if (!ctx.ui || !ctx.ui.page) {
|
|
@@ -19,7 +19,9 @@ export function registerActionSteps(registry: StepRegistry): void {
|
|
|
19
19
|
if (!input.selector) {
|
|
20
20
|
throw new Error('Missing "selector" in step.with for op "ui.click"');
|
|
21
21
|
}
|
|
22
|
-
await page.click(input.selector
|
|
22
|
+
await page.click(input.selector, {
|
|
23
|
+
timeout: ctx.ui?.resolveTimeout(input.timeoutMs),
|
|
24
|
+
});
|
|
23
25
|
});
|
|
24
26
|
|
|
25
27
|
registry.register("ui.press", async (ctx: TestContext, step: OpStep) => {
|
|
@@ -31,6 +33,8 @@ export function registerActionSteps(registry: StepRegistry): void {
|
|
|
31
33
|
if (!input.key) {
|
|
32
34
|
throw new Error('Missing "key" in step.with for op "ui.press"');
|
|
33
35
|
}
|
|
34
|
-
await page.press(input.selector, input.key
|
|
36
|
+
await page.press(input.selector, input.key, {
|
|
37
|
+
timeout: ctx.ui?.resolveTimeout(input.timeoutMs),
|
|
38
|
+
});
|
|
35
39
|
});
|
|
36
40
|
}
|
|
@@ -2,8 +2,13 @@ import type { TestContext } from "../../contracts/runtime-context.types";
|
|
|
2
2
|
import type { OpStep } from "../../contracts/testing-metadata.types";
|
|
3
3
|
import { StepRegistry } from "../../core/step-registry";
|
|
4
4
|
|
|
5
|
-
type VisibleInput = { selector: string };
|
|
6
|
-
type ExpectTextInput = {
|
|
5
|
+
type VisibleInput = { selector: string; timeoutMs?: number };
|
|
6
|
+
type ExpectTextInput = {
|
|
7
|
+
selector: string;
|
|
8
|
+
equals?: string;
|
|
9
|
+
contains?: string;
|
|
10
|
+
timeoutMs?: number;
|
|
11
|
+
};
|
|
7
12
|
|
|
8
13
|
function requirePage(ctx: TestContext, op: string) {
|
|
9
14
|
if (!ctx.ui || !ctx.ui.page) {
|
|
@@ -19,7 +24,10 @@ export function registerAssertionSteps(registry: StepRegistry): void {
|
|
|
19
24
|
if (!input.selector) {
|
|
20
25
|
throw new Error('Missing "selector" in step.with for op "ui.expectVisible"');
|
|
21
26
|
}
|
|
22
|
-
await page.waitForSelector(input.selector, {
|
|
27
|
+
await page.waitForSelector(input.selector, {
|
|
28
|
+
state: "visible",
|
|
29
|
+
timeout: ctx.ui?.resolveTimeout(input.timeoutMs),
|
|
30
|
+
});
|
|
23
31
|
});
|
|
24
32
|
|
|
25
33
|
registry.register("ui.expectHidden", async (ctx: TestContext, step: OpStep) => {
|
|
@@ -28,7 +36,10 @@ export function registerAssertionSteps(registry: StepRegistry): void {
|
|
|
28
36
|
if (!input.selector) {
|
|
29
37
|
throw new Error('Missing "selector" in step.with for op "ui.expectHidden"');
|
|
30
38
|
}
|
|
31
|
-
await page.waitForSelector(input.selector, {
|
|
39
|
+
await page.waitForSelector(input.selector, {
|
|
40
|
+
state: "hidden",
|
|
41
|
+
timeout: ctx.ui?.resolveTimeout(input.timeoutMs),
|
|
42
|
+
});
|
|
32
43
|
});
|
|
33
44
|
|
|
34
45
|
registry.register("ui.expectText", async (ctx: TestContext, step: OpStep) => {
|
|
@@ -38,7 +49,9 @@ export function registerAssertionSteps(registry: StepRegistry): void {
|
|
|
38
49
|
throw new Error('Missing "selector" in step.with for op "ui.expectText"');
|
|
39
50
|
}
|
|
40
51
|
|
|
41
|
-
const text = await page
|
|
52
|
+
const text = await page
|
|
53
|
+
.locator(input.selector)
|
|
54
|
+
.innerText({ timeout: ctx.ui?.resolveTimeout(input.timeoutMs) });
|
|
42
55
|
if (input.equals !== undefined) {
|
|
43
56
|
if (text !== input.equals) {
|
|
44
57
|
throw new Error(
|
|
@@ -4,9 +4,13 @@ import type { TestContext } from "../../contracts/runtime-context.types";
|
|
|
4
4
|
import type { OpStep } from "../../contracts/testing-metadata.types";
|
|
5
5
|
import { StepRegistry } from "../../core/step-registry";
|
|
6
6
|
|
|
7
|
-
type FillInput = { selector: string; value: string };
|
|
8
|
-
type SelectInput = { selector: string; value: string };
|
|
9
|
-
type UploadFileInput = {
|
|
7
|
+
type FillInput = { selector: string; value: string; timeoutMs?: number };
|
|
8
|
+
type SelectInput = { selector: string; value: string; timeoutMs?: number };
|
|
9
|
+
type UploadFileInput = {
|
|
10
|
+
selector: string;
|
|
11
|
+
filePath: string | string[];
|
|
12
|
+
timeoutMs?: number;
|
|
13
|
+
};
|
|
10
14
|
|
|
11
15
|
function requirePage(ctx: TestContext, op: string) {
|
|
12
16
|
if (!ctx.ui || !ctx.ui.page) {
|
|
@@ -25,7 +29,9 @@ export function registerFormSteps(registry: StepRegistry): void {
|
|
|
25
29
|
if (input.value === undefined) {
|
|
26
30
|
throw new Error('Missing "value" in step.with for op "ui.fill"');
|
|
27
31
|
}
|
|
28
|
-
await page.fill(input.selector, String(input.value)
|
|
32
|
+
await page.fill(input.selector, String(input.value), {
|
|
33
|
+
timeout: ctx.ui?.resolveTimeout(input.timeoutMs),
|
|
34
|
+
});
|
|
29
35
|
});
|
|
30
36
|
|
|
31
37
|
registry.register("ui.select", async (ctx: TestContext, step: OpStep) => {
|
|
@@ -37,7 +43,9 @@ export function registerFormSteps(registry: StepRegistry): void {
|
|
|
37
43
|
if (input.value === undefined) {
|
|
38
44
|
throw new Error('Missing "value" in step.with for op "ui.select"');
|
|
39
45
|
}
|
|
40
|
-
await page.selectOption(input.selector, String(input.value)
|
|
46
|
+
await page.selectOption(input.selector, String(input.value), {
|
|
47
|
+
timeout: ctx.ui?.resolveTimeout(input.timeoutMs),
|
|
48
|
+
});
|
|
41
49
|
});
|
|
42
50
|
|
|
43
51
|
registry.register("ui.uploadFile", async (ctx: TestContext, step: OpStep) => {
|
|
@@ -53,6 +61,8 @@ export function registerFormSteps(registry: StepRegistry): void {
|
|
|
53
61
|
const resolved = Array.isArray(input.filePath)
|
|
54
62
|
? input.filePath.map((p) => path.resolve(cwd, String(p)))
|
|
55
63
|
: path.resolve(cwd, String(input.filePath));
|
|
56
|
-
await page.setInputFiles(input.selector, resolved
|
|
64
|
+
await page.setInputFiles(input.selector, resolved, {
|
|
65
|
+
timeout: ctx.ui?.resolveTimeout(input.timeoutMs),
|
|
66
|
+
});
|
|
57
67
|
});
|
|
58
68
|
}
|
|
@@ -28,7 +28,7 @@ export function registerManualSteps(registry: StepRegistry): void {
|
|
|
28
28
|
const inputConfig = (step.with ?? {}) as WaitForManualInput;
|
|
29
29
|
const message = inputConfig.message?.trim() || "Manual interaction required.";
|
|
30
30
|
const prompt = inputConfig.prompt?.trim() || "Press Enter to continue...";
|
|
31
|
-
const timeoutMs = inputConfig.timeoutMs;
|
|
31
|
+
const timeoutMs = ctx.ui?.resolveTimeout(inputConfig.timeoutMs);
|
|
32
32
|
const bringToFront = inputConfig.bringToFront ?? true;
|
|
33
33
|
|
|
34
34
|
if (ctx.ui?.isHeadless()) {
|
|
@@ -2,7 +2,7 @@ import type { TestContext } from "../../contracts/runtime-context.types";
|
|
|
2
2
|
import type { OpStep } from "../../contracts/testing-metadata.types";
|
|
3
3
|
import { StepRegistry } from "../../core/step-registry";
|
|
4
4
|
|
|
5
|
-
type GotoInput = { url: string };
|
|
5
|
+
type GotoInput = { url: string; timeoutMs?: number };
|
|
6
6
|
type ExpectUrlInput = { equals?: string; contains?: string };
|
|
7
7
|
|
|
8
8
|
function requirePage(ctx: TestContext, op: string) {
|
|
@@ -20,7 +20,9 @@ export function registerNavigationSteps(registry: StepRegistry): void {
|
|
|
20
20
|
throw new Error('Missing "url" in step.with for op "ui.goto"');
|
|
21
21
|
}
|
|
22
22
|
const url = ctx.ui?.resolveUrl(input.url) ?? input.url;
|
|
23
|
-
await page.goto(url
|
|
23
|
+
await page.goto(url, {
|
|
24
|
+
timeout: ctx.ui?.resolveNavigationTimeout(input.timeoutMs),
|
|
25
|
+
});
|
|
24
26
|
});
|
|
25
27
|
|
|
26
28
|
registry.register("ui.expectUrl", async (ctx: TestContext, step: OpStep) => {
|