@testsmith/testblocks 0.9.4 → 0.9.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/index.js +4 -1
- package/dist/client/assets/index-B8OSvcUg.css +1 -0
- package/dist/client/assets/index-CMMJHs_d.js +2197 -0
- package/dist/client/assets/index-CMMJHs_d.js.map +1 -0
- package/dist/client/index.html +2 -2
- package/dist/core/blocks/api/ApiAssertBodyContainsBlock.d.ts +13 -0
- package/dist/core/blocks/api/ApiAssertBodyContainsBlock.js +40 -0
- package/dist/core/blocks/api/ApiAssertStatusBlock.d.ts +13 -0
- package/dist/core/blocks/api/ApiAssertStatusBlock.js +35 -0
- package/dist/core/blocks/api/ApiClearHeadersBlock.d.ts +13 -0
- package/dist/core/blocks/api/ApiClearHeadersBlock.js +25 -0
- package/dist/core/blocks/api/ApiDeleteBlock.d.ts +13 -0
- package/dist/core/blocks/api/ApiDeleteBlock.js +37 -0
- package/dist/core/blocks/api/ApiExtractBlock.d.ts +14 -0
- package/dist/core/blocks/api/ApiExtractBlock.js +40 -0
- package/dist/core/blocks/api/ApiExtractJsonPathBlock.d.ts +13 -0
- package/dist/core/blocks/api/ApiExtractJsonPathBlock.js +47 -0
- package/dist/core/blocks/api/ApiExtractXPathBlock.d.ts +13 -0
- package/dist/core/blocks/api/ApiExtractXPathBlock.js +70 -0
- package/dist/core/blocks/api/ApiGetBlock.d.ts +13 -0
- package/dist/core/blocks/api/ApiGetBlock.js +36 -0
- package/dist/core/blocks/api/ApiHeadersBlock.d.ts +14 -0
- package/dist/core/blocks/api/ApiHeadersBlock.js +44 -0
- package/dist/core/blocks/api/ApiJsonBodyBlock.d.ts +14 -0
- package/dist/core/blocks/api/ApiJsonBodyBlock.js +28 -0
- package/dist/core/blocks/api/ApiPatchBlock.d.ts +13 -0
- package/dist/core/blocks/api/ApiPatchBlock.js +47 -0
- package/dist/core/blocks/api/ApiPostBlock.d.ts +13 -0
- package/dist/core/blocks/api/ApiPostBlock.js +47 -0
- package/dist/core/blocks/api/ApiPutBlock.d.ts +13 -0
- package/dist/core/blocks/api/ApiPutBlock.js +47 -0
- package/dist/core/blocks/api/ApiSetHeaderBlock.d.ts +13 -0
- package/dist/core/blocks/api/ApiSetHeaderBlock.js +37 -0
- package/dist/core/blocks/api/ApiSetHeadersBlock.d.ts +13 -0
- package/dist/core/blocks/api/ApiSetHeadersBlock.js +41 -0
- package/dist/core/blocks/api/index.d.ts +25 -0
- package/dist/core/blocks/api/index.js +83 -0
- package/dist/core/blocks/base/Block.d.ts +59 -0
- package/dist/core/blocks/base/Block.js +151 -0
- package/dist/core/blocks/base/ContainerBlock.d.ts +14 -0
- package/dist/core/blocks/base/ContainerBlock.js +16 -0
- package/dist/core/blocks/base/ControlFlowBlock.d.ts +13 -0
- package/dist/core/blocks/base/ControlFlowBlock.js +17 -0
- package/dist/core/blocks/base/StatementBlock.d.ts +9 -0
- package/dist/core/blocks/base/StatementBlock.js +16 -0
- package/dist/core/blocks/base/ValueBlock.d.ts +12 -0
- package/dist/core/blocks/base/ValueBlock.js +16 -0
- package/dist/core/blocks/base/index.d.ts +5 -0
- package/dist/core/blocks/base/index.js +13 -0
- package/dist/core/blocks/data/DataCsvBlock.d.ts +14 -0
- package/dist/core/blocks/data/DataCsvBlock.js +51 -0
- package/dist/core/blocks/data/DataDefineBlock.d.ts +14 -0
- package/dist/core/blocks/data/DataDefineBlock.js +28 -0
- package/dist/core/blocks/data/DataForeachBlock.d.ts +13 -0
- package/dist/core/blocks/data/DataForeachBlock.js +37 -0
- package/dist/core/blocks/data/DataFromVariableBlock.d.ts +14 -0
- package/dist/core/blocks/data/DataFromVariableBlock.js +27 -0
- package/dist/core/blocks/data/DataGetCurrentBlock.d.ts +14 -0
- package/dist/core/blocks/data/DataGetCurrentBlock.js +34 -0
- package/dist/core/blocks/data/DataGetIndexBlock.d.ts +14 -0
- package/dist/core/blocks/data/DataGetIndexBlock.js +24 -0
- package/dist/core/blocks/data/DataGetNameBlock.d.ts +14 -0
- package/dist/core/blocks/data/DataGetNameBlock.js +24 -0
- package/dist/core/blocks/data/DataRangeBlock.d.ts +14 -0
- package/dist/core/blocks/data/DataRangeBlock.js +40 -0
- package/dist/core/blocks/data/DataRowBlock.d.ts +14 -0
- package/dist/core/blocks/data/DataRowBlock.js +33 -0
- package/dist/core/blocks/data/DataTableBlock.d.ts +14 -0
- package/dist/core/blocks/data/DataTableBlock.js +51 -0
- package/dist/core/blocks/data/index.d.ts +20 -0
- package/dist/core/blocks/data/index.js +57 -0
- package/dist/core/blocks/index.d.ts +66 -5
- package/dist/core/blocks/index.js +134 -35
- package/dist/core/blocks/lifecycle/LifecycleAfterAllBlock.d.ts +15 -0
- package/dist/core/blocks/lifecycle/LifecycleAfterAllBlock.js +27 -0
- package/dist/core/blocks/lifecycle/LifecycleAfterEachBlock.d.ts +15 -0
- package/dist/core/blocks/lifecycle/LifecycleAfterEachBlock.js +27 -0
- package/dist/core/blocks/lifecycle/LifecycleBeforeAllBlock.d.ts +15 -0
- package/dist/core/blocks/lifecycle/LifecycleBeforeAllBlock.js +28 -0
- package/dist/core/blocks/lifecycle/LifecycleBeforeEachBlock.d.ts +15 -0
- package/dist/core/blocks/lifecycle/LifecycleBeforeEachBlock.js +27 -0
- package/dist/core/blocks/lifecycle/LifecycleOnFailureBlock.d.ts +13 -0
- package/dist/core/blocks/lifecycle/LifecycleOnFailureBlock.js +25 -0
- package/dist/core/blocks/lifecycle/LifecycleRetryBlock.d.ts +13 -0
- package/dist/core/blocks/lifecycle/LifecycleRetryBlock.js +29 -0
- package/dist/core/blocks/lifecycle/LifecycleSetupBlock.d.ts +13 -0
- package/dist/core/blocks/lifecycle/LifecycleSetupBlock.js +27 -0
- package/dist/core/blocks/lifecycle/LifecycleSkipIfBlock.d.ts +13 -0
- package/dist/core/blocks/lifecycle/LifecycleSkipIfBlock.js +31 -0
- package/dist/core/blocks/lifecycle/LifecycleTeardownBlock.d.ts +13 -0
- package/dist/core/blocks/lifecycle/LifecycleTeardownBlock.js +27 -0
- package/dist/core/blocks/lifecycle/TestCaseBlock.d.ts +21 -0
- package/dist/core/blocks/lifecycle/TestCaseBlock.js +72 -0
- package/dist/core/blocks/lifecycle/TestCaseDataDrivenBlock.d.ts +21 -0
- package/dist/core/blocks/lifecycle/TestCaseDataDrivenBlock.js +102 -0
- package/dist/core/blocks/lifecycle/index.d.ts +21 -0
- package/dist/core/blocks/lifecycle/index.js +63 -0
- package/dist/core/blocks/logic/LogicArrayBlock.d.ts +14 -0
- package/dist/core/blocks/logic/LogicArrayBlock.js +28 -0
- package/dist/core/blocks/logic/LogicAssertBlock.d.ts +13 -0
- package/dist/core/blocks/logic/LogicAssertBlock.js +32 -0
- package/dist/core/blocks/logic/LogicBooleanBlock.d.ts +14 -0
- package/dist/core/blocks/logic/LogicBooleanBlock.js +26 -0
- package/dist/core/blocks/logic/LogicBooleanOpBlock.d.ts +14 -0
- package/dist/core/blocks/logic/LogicBooleanOpBlock.js +31 -0
- package/dist/core/blocks/logic/LogicCommentBlock.d.ts +13 -0
- package/dist/core/blocks/logic/LogicCommentBlock.js +26 -0
- package/dist/core/blocks/logic/LogicCompareBlock.d.ts +14 -0
- package/dist/core/blocks/logic/LogicCompareBlock.js +52 -0
- package/dist/core/blocks/logic/LogicFailBlock.d.ts +16 -0
- package/dist/core/blocks/logic/LogicFailBlock.js +30 -0
- package/dist/core/blocks/logic/LogicForeachBlock.d.ts +13 -0
- package/dist/core/blocks/logic/LogicForeachBlock.js +29 -0
- package/dist/core/blocks/logic/LogicGetVariableBlock.d.ts +14 -0
- package/dist/core/blocks/logic/LogicGetVariableBlock.js +27 -0
- package/dist/core/blocks/logic/LogicIfBlock.d.ts +13 -0
- package/dist/core/blocks/logic/LogicIfBlock.js +36 -0
- package/dist/core/blocks/logic/LogicLogBlock.d.ts +13 -0
- package/dist/core/blocks/logic/LogicLogBlock.js +30 -0
- package/dist/core/blocks/logic/LogicNotBlock.d.ts +14 -0
- package/dist/core/blocks/logic/LogicNotBlock.js +26 -0
- package/dist/core/blocks/logic/LogicNumberBlock.d.ts +14 -0
- package/dist/core/blocks/logic/LogicNumberBlock.js +26 -0
- package/dist/core/blocks/logic/LogicObjectBlock.d.ts +14 -0
- package/dist/core/blocks/logic/LogicObjectBlock.js +28 -0
- package/dist/core/blocks/logic/LogicRepeatBlock.d.ts +13 -0
- package/dist/core/blocks/logic/LogicRepeatBlock.js +27 -0
- package/dist/core/blocks/logic/LogicSetVariableBlock.d.ts +13 -0
- package/dist/core/blocks/logic/LogicSetVariableBlock.js +34 -0
- package/dist/core/blocks/logic/LogicTextBlock.d.ts +14 -0
- package/dist/core/blocks/logic/LogicTextBlock.js +27 -0
- package/dist/core/blocks/logic/LogicTryCatchBlock.d.ts +13 -0
- package/dist/core/blocks/logic/LogicTryCatchBlock.js +26 -0
- package/dist/core/blocks/logic/index.d.ts +28 -0
- package/dist/core/blocks/logic/index.js +95 -0
- package/dist/core/blocks/playwright/assertions/WebAssertAccessibleDescriptionBlock.d.ts +13 -0
- package/dist/core/blocks/playwright/assertions/WebAssertAccessibleDescriptionBlock.js +41 -0
- package/dist/core/blocks/playwright/assertions/WebAssertAccessibleNameBlock.d.ts +13 -0
- package/dist/core/blocks/playwright/assertions/WebAssertAccessibleNameBlock.js +41 -0
- package/dist/core/blocks/playwright/assertions/WebAssertAttachedBlock.d.ts +13 -0
- package/dist/core/blocks/playwright/assertions/WebAssertAttachedBlock.js +39 -0
- package/dist/core/blocks/playwright/assertions/WebAssertAttributeBlock.d.ts +13 -0
- package/dist/core/blocks/playwright/assertions/WebAssertAttributeBlock.js +44 -0
- package/dist/core/blocks/playwright/assertions/WebAssertCheckedBlock.d.ts +13 -0
- package/dist/core/blocks/playwright/assertions/WebAssertCheckedBlock.js +48 -0
- package/dist/core/blocks/playwright/assertions/WebAssertClassBlock.d.ts +13 -0
- package/dist/core/blocks/playwright/assertions/WebAssertClassBlock.js +43 -0
- package/dist/core/blocks/playwright/assertions/WebAssertCountBlock.d.ts +13 -0
- package/dist/core/blocks/playwright/assertions/WebAssertCountBlock.js +41 -0
- package/dist/core/blocks/playwright/assertions/WebAssertCssBlock.d.ts +13 -0
- package/dist/core/blocks/playwright/assertions/WebAssertCssBlock.js +44 -0
- package/dist/core/blocks/playwright/assertions/WebAssertDisabledBlock.d.ts +13 -0
- package/dist/core/blocks/playwright/assertions/WebAssertDisabledBlock.js +39 -0
- package/dist/core/blocks/playwright/assertions/WebAssertEditableBlock.d.ts +13 -0
- package/dist/core/blocks/playwright/assertions/WebAssertEditableBlock.js +39 -0
- package/dist/core/blocks/playwright/assertions/WebAssertEmptyBlock.d.ts +13 -0
- package/dist/core/blocks/playwright/assertions/WebAssertEmptyBlock.js +39 -0
- package/dist/core/blocks/playwright/assertions/WebAssertEnabledBlock.d.ts +13 -0
- package/dist/core/blocks/playwright/assertions/WebAssertEnabledBlock.js +39 -0
- package/dist/core/blocks/playwright/assertions/WebAssertFocusedBlock.d.ts +13 -0
- package/dist/core/blocks/playwright/assertions/WebAssertFocusedBlock.js +39 -0
- package/dist/core/blocks/playwright/assertions/WebAssertIdBlock.d.ts +13 -0
- package/dist/core/blocks/playwright/assertions/WebAssertIdBlock.js +41 -0
- package/dist/core/blocks/playwright/assertions/WebAssertInViewportBlock.d.ts +13 -0
- package/dist/core/blocks/playwright/assertions/WebAssertInViewportBlock.js +39 -0
- package/dist/core/blocks/playwright/assertions/WebAssertNotVisibleBlock.d.ts +13 -0
- package/dist/core/blocks/playwright/assertions/WebAssertNotVisibleBlock.js +39 -0
- package/dist/core/blocks/playwright/assertions/WebAssertRoleBlock.d.ts +13 -0
- package/dist/core/blocks/playwright/assertions/WebAssertRoleBlock.js +69 -0
- package/dist/core/blocks/playwright/assertions/WebAssertTextContainsBlock.d.ts +13 -0
- package/dist/core/blocks/playwright/assertions/WebAssertTextContainsBlock.js +41 -0
- package/dist/core/blocks/playwright/assertions/WebAssertTextEqualsBlock.d.ts +13 -0
- package/dist/core/blocks/playwright/assertions/WebAssertTextEqualsBlock.js +41 -0
- package/dist/core/blocks/playwright/assertions/WebAssertTitleContainsBlock.d.ts +13 -0
- package/dist/core/blocks/playwright/assertions/WebAssertTitleContainsBlock.js +39 -0
- package/dist/core/blocks/playwright/assertions/WebAssertTitleEqualsBlock.d.ts +13 -0
- package/dist/core/blocks/playwright/assertions/WebAssertTitleEqualsBlock.js +36 -0
- package/dist/core/blocks/playwright/assertions/WebAssertUrlContainsBlock.d.ts +13 -0
- package/dist/core/blocks/playwright/assertions/WebAssertUrlContainsBlock.js +40 -0
- package/dist/core/blocks/playwright/assertions/WebAssertUrlEqualsBlock.d.ts +13 -0
- package/dist/core/blocks/playwright/assertions/WebAssertUrlEqualsBlock.js +37 -0
- package/dist/core/blocks/playwright/assertions/WebAssertValueBlock.d.ts +13 -0
- package/dist/core/blocks/playwright/assertions/WebAssertValueBlock.js +43 -0
- package/dist/core/blocks/playwright/assertions/WebAssertValueContainsBlock.d.ts +13 -0
- package/dist/core/blocks/playwright/assertions/WebAssertValueContainsBlock.js +43 -0
- package/dist/core/blocks/playwright/assertions/WebAssertVisibleBlock.d.ts +13 -0
- package/dist/core/blocks/playwright/assertions/WebAssertVisibleBlock.js +39 -0
- package/dist/core/blocks/playwright/assertions/index.d.ts +36 -0
- package/dist/core/blocks/playwright/assertions/index.js +127 -0
- package/dist/core/blocks/playwright/index.d.ts +16 -0
- package/dist/core/blocks/playwright/index.js +28 -3
- package/dist/core/blocks/playwright/interactions/WebCheckboxBlock.d.ts +13 -0
- package/dist/core/blocks/playwright/interactions/WebCheckboxBlock.js +43 -0
- package/dist/core/blocks/playwright/interactions/WebClickBlock.d.ts +13 -0
- package/dist/core/blocks/playwright/interactions/WebClickBlock.js +34 -0
- package/dist/core/blocks/playwright/interactions/WebDragAndDropBlock.d.ts +13 -0
- package/dist/core/blocks/playwright/interactions/WebDragAndDropBlock.js +37 -0
- package/dist/core/blocks/playwright/interactions/WebFillBlock.d.ts +13 -0
- package/dist/core/blocks/playwright/interactions/WebFillBlock.js +38 -0
- package/dist/core/blocks/playwright/interactions/WebFocusBlock.d.ts +13 -0
- package/dist/core/blocks/playwright/interactions/WebFocusBlock.js +34 -0
- package/dist/core/blocks/playwright/interactions/WebHoverBlock.d.ts +13 -0
- package/dist/core/blocks/playwright/interactions/WebHoverBlock.js +34 -0
- package/dist/core/blocks/playwright/interactions/WebPressKeyBlock.d.ts +13 -0
- package/dist/core/blocks/playwright/interactions/WebPressKeyBlock.js +37 -0
- package/dist/core/blocks/playwright/interactions/WebScrollIntoViewBlock.d.ts +13 -0
- package/dist/core/blocks/playwright/interactions/WebScrollIntoViewBlock.js +34 -0
- package/dist/core/blocks/playwright/interactions/WebSelectBlock.d.ts +13 -0
- package/dist/core/blocks/playwright/interactions/WebSelectBlock.js +37 -0
- package/dist/core/blocks/playwright/interactions/WebTypeBlock.d.ts +13 -0
- package/dist/core/blocks/playwright/interactions/WebTypeBlock.js +41 -0
- package/dist/core/blocks/playwright/interactions/WebUploadFileBlock.d.ts +13 -0
- package/dist/core/blocks/playwright/interactions/WebUploadFileBlock.js +39 -0
- package/dist/core/blocks/playwright/interactions/index.d.ts +21 -0
- package/dist/core/blocks/playwright/interactions/index.js +56 -0
- package/dist/core/blocks/playwright/navigation/WebNavigateBlock.d.ts +13 -0
- package/dist/core/blocks/playwright/navigation/WebNavigateBlock.js +36 -0
- package/dist/core/blocks/playwright/navigation/WebScreenshotBlock.d.ts +13 -0
- package/dist/core/blocks/playwright/navigation/WebScreenshotBlock.js +36 -0
- package/dist/core/blocks/playwright/navigation/WebWaitBlock.d.ts +13 -0
- package/dist/core/blocks/playwright/navigation/WebWaitBlock.js +32 -0
- package/dist/core/blocks/playwright/navigation/WebWaitForElementBlock.d.ts +13 -0
- package/dist/core/blocks/playwright/navigation/WebWaitForElementBlock.js +37 -0
- package/dist/core/blocks/playwright/navigation/WebWaitForUrlBlock.d.ts +13 -0
- package/dist/core/blocks/playwright/navigation/WebWaitForUrlBlock.js +34 -0
- package/dist/core/blocks/playwright/navigation/index.d.ts +15 -0
- package/dist/core/blocks/playwright/navigation/index.js +32 -0
- package/dist/core/blocks/playwright/retrieval/WebCountElementsBlock.d.ts +16 -0
- package/dist/core/blocks/playwright/retrieval/WebCountElementsBlock.js +36 -0
- package/dist/core/blocks/playwright/retrieval/WebGetAttributeBlock.d.ts +16 -0
- package/dist/core/blocks/playwright/retrieval/WebGetAttributeBlock.js +42 -0
- package/dist/core/blocks/playwright/retrieval/WebGetInputValueBlock.d.ts +16 -0
- package/dist/core/blocks/playwright/retrieval/WebGetInputValueBlock.js +40 -0
- package/dist/core/blocks/playwright/retrieval/WebGetTextBlock.d.ts +16 -0
- package/dist/core/blocks/playwright/retrieval/WebGetTextBlock.js +40 -0
- package/dist/core/blocks/playwright/retrieval/WebGetTitleBlock.d.ts +16 -0
- package/dist/core/blocks/playwright/retrieval/WebGetTitleBlock.js +31 -0
- package/dist/core/blocks/playwright/retrieval/WebGetUrlBlock.d.ts +16 -0
- package/dist/core/blocks/playwright/retrieval/WebGetUrlBlock.js +31 -0
- package/dist/core/blocks/playwright/retrieval/index.d.ts +16 -0
- package/dist/core/blocks/playwright/retrieval/index.js +36 -0
- package/dist/core/blocks/playwright/types.d.ts +14 -0
- package/dist/core/blocks/procedures/ProcedureCallBlock.d.ts +13 -0
- package/dist/core/blocks/procedures/ProcedureCallBlock.js +66 -0
- package/dist/core/blocks/procedures/ProcedureCallWithReturnBlock.d.ts +14 -0
- package/dist/core/blocks/procedures/ProcedureCallWithReturnBlock.js +51 -0
- package/dist/core/blocks/procedures/ProcedureDefineBlock.d.ts +15 -0
- package/dist/core/blocks/procedures/ProcedureDefineBlock.js +59 -0
- package/dist/core/blocks/procedures/ProcedureFillFormBlock.d.ts +13 -0
- package/dist/core/blocks/procedures/ProcedureFillFormBlock.js +30 -0
- package/dist/core/blocks/procedures/ProcedureGetParamBlock.d.ts +14 -0
- package/dist/core/blocks/procedures/ProcedureGetParamBlock.js +33 -0
- package/dist/core/blocks/procedures/ProcedureInlineBlock.d.ts +14 -0
- package/dist/core/blocks/procedures/ProcedureInlineBlock.js +31 -0
- package/dist/core/blocks/procedures/ProcedureLoginBlock.d.ts +13 -0
- package/dist/core/blocks/procedures/ProcedureLoginBlock.js +37 -0
- package/dist/core/blocks/procedures/ProcedureMapBlock.d.ts +14 -0
- package/dist/core/blocks/procedures/ProcedureMapBlock.js +36 -0
- package/dist/core/blocks/procedures/ProcedureReturnBlock.d.ts +15 -0
- package/dist/core/blocks/procedures/ProcedureReturnBlock.js +28 -0
- package/dist/core/blocks/procedures/ProcedureWaitAndClickBlock.d.ts +13 -0
- package/dist/core/blocks/procedures/ProcedureWaitAndClickBlock.js +32 -0
- package/dist/core/blocks/procedures/index.d.ts +21 -0
- package/dist/core/blocks/procedures/index.js +62 -0
- package/dist/core/blocks/{procedures.d.ts → procedures/procedureRegistry.d.ts} +10 -2
- package/dist/core/blocks/procedures/procedureRegistry.js +27 -0
- package/dist/core/blocks/utils/apiUtils.d.ts +81 -0
- package/dist/core/blocks/utils/apiUtils.js +176 -0
- package/dist/core/blocks/utils/index.d.ts +2 -0
- package/dist/core/blocks/utils/index.js +16 -0
- package/dist/core/blocks/utils/variableUtils.d.ts +19 -0
- package/dist/core/blocks/utils/variableUtils.js +69 -0
- package/dist/server/index.js +117 -11
- package/dist/server/openApiParser.d.ts +82 -0
- package/dist/server/openApiParser.js +495 -0
- package/dist/server/startServer.d.ts +1 -0
- package/dist/server/startServer.js +164 -0
- package/package.json +4 -2
- package/dist/client/assets/index-BLBBQ6Rn.js +0 -2195
- package/dist/client/assets/index-BLBBQ6Rn.js.map +0 -1
- package/dist/client/assets/index-qjoPPl9y.css +0 -1
- package/dist/core/blocks/api.d.ts +0 -2
- package/dist/core/blocks/api.js +0 -607
- package/dist/core/blocks/data-driven.d.ts +0 -2
- package/dist/core/blocks/data-driven.js +0 -245
- package/dist/core/blocks/lifecycle.d.ts +0 -2
- package/dist/core/blocks/lifecycle.js +0 -201
- package/dist/core/blocks/logic.d.ts +0 -2
- package/dist/core/blocks/logic.js +0 -360
- package/dist/core/blocks/playwright/assertions.d.ts +0 -5
- package/dist/core/blocks/playwright/assertions.js +0 -311
- package/dist/core/blocks/playwright/interactions.d.ts +0 -5
- package/dist/core/blocks/playwright/interactions.js +0 -208
- package/dist/core/blocks/playwright/navigation.d.ts +0 -5
- package/dist/core/blocks/playwright/navigation.js +0 -131
- package/dist/core/blocks/playwright/retrieval.d.ts +0 -5
- package/dist/core/blocks/playwright/retrieval.js +0 -153
- package/dist/core/blocks/playwright.d.ts +0 -13
- package/dist/core/blocks/playwright.js +0 -17
- package/dist/core/blocks/procedures.js +0 -321
|
@@ -0,0 +1,495 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.parseOpenApiSpec = parseOpenApiSpec;
|
|
40
|
+
exports.generateTestFiles = generateTestFiles;
|
|
41
|
+
const swagger_parser_1 = __importDefault(require("@apidevtools/swagger-parser"));
|
|
42
|
+
/**
|
|
43
|
+
* Parse an OpenAPI/Swagger spec from a URL or content string
|
|
44
|
+
*/
|
|
45
|
+
async function parseOpenApiSpec(source, isUrl = true) {
|
|
46
|
+
let api;
|
|
47
|
+
if (isUrl) {
|
|
48
|
+
api = await swagger_parser_1.default.dereference(source);
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
// Parse from content string (JSON or YAML)
|
|
52
|
+
const content = source.trim();
|
|
53
|
+
let parsed;
|
|
54
|
+
if (content.startsWith('{')) {
|
|
55
|
+
parsed = JSON.parse(content);
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
// Import yaml dynamically
|
|
59
|
+
const yaml = await Promise.resolve().then(() => __importStar(require('yaml')));
|
|
60
|
+
parsed = yaml.parse(content);
|
|
61
|
+
}
|
|
62
|
+
api = await swagger_parser_1.default.dereference(parsed);
|
|
63
|
+
}
|
|
64
|
+
return extractSpecInfo(api);
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Extract structured information from a parsed OpenAPI spec
|
|
68
|
+
*/
|
|
69
|
+
function extractSpecInfo(api) {
|
|
70
|
+
const isV3 = 'openapi' in api;
|
|
71
|
+
// Extract info
|
|
72
|
+
const info = {
|
|
73
|
+
title: api.info.title,
|
|
74
|
+
version: api.info.version,
|
|
75
|
+
description: api.info.description,
|
|
76
|
+
};
|
|
77
|
+
// Extract servers
|
|
78
|
+
const servers = [];
|
|
79
|
+
if (isV3) {
|
|
80
|
+
const v3Api = api;
|
|
81
|
+
if (v3Api.servers) {
|
|
82
|
+
servers.push(...v3Api.servers.map(s => ({ url: s.url, description: s.description })));
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
const v2Api = api;
|
|
87
|
+
const scheme = v2Api.schemes?.[0] || 'https';
|
|
88
|
+
const host = v2Api.host || 'localhost';
|
|
89
|
+
const basePath = v2Api.basePath || '';
|
|
90
|
+
servers.push({ url: `${scheme}://${host}${basePath}` });
|
|
91
|
+
}
|
|
92
|
+
// Extract security schemes
|
|
93
|
+
const securitySchemes = {};
|
|
94
|
+
if (isV3) {
|
|
95
|
+
const v3Api = api;
|
|
96
|
+
const schemes = v3Api.components?.securitySchemes || {};
|
|
97
|
+
for (const [name, scheme] of Object.entries(schemes)) {
|
|
98
|
+
if ('type' in scheme) {
|
|
99
|
+
securitySchemes[name] = extractSecurityScheme(scheme);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
const v2Api = api;
|
|
105
|
+
const schemes = v2Api.securityDefinitions || {};
|
|
106
|
+
for (const [name, scheme] of Object.entries(schemes)) {
|
|
107
|
+
securitySchemes[name] = extractSecuritySchemeV2(scheme);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
// Extract tags
|
|
111
|
+
const tags = (api.tags || []).map(t => ({
|
|
112
|
+
name: t.name,
|
|
113
|
+
description: t.description,
|
|
114
|
+
}));
|
|
115
|
+
// Extract endpoints
|
|
116
|
+
const endpoints = [];
|
|
117
|
+
const paths = api.paths || {};
|
|
118
|
+
for (const [path, pathItem] of Object.entries(paths)) {
|
|
119
|
+
if (!pathItem)
|
|
120
|
+
continue;
|
|
121
|
+
const methods = ['get', 'post', 'put', 'patch', 'delete'];
|
|
122
|
+
for (const method of methods) {
|
|
123
|
+
const operation = pathItem[method];
|
|
124
|
+
if (!operation)
|
|
125
|
+
continue;
|
|
126
|
+
const endpoint = extractEndpoint(path, method, operation, pathItem, isV3);
|
|
127
|
+
endpoints.push(endpoint);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
return { info, servers, endpoints, securitySchemes, tags };
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Extract a single endpoint from an operation
|
|
134
|
+
*/
|
|
135
|
+
function extractEndpoint(path, method, operation, pathItem, isV3) {
|
|
136
|
+
// Combine path-level and operation-level parameters
|
|
137
|
+
const pathParams = (pathItem.parameters || []);
|
|
138
|
+
const opParams = (operation.parameters || []);
|
|
139
|
+
const allParams = [...pathParams, ...opParams];
|
|
140
|
+
// Extract parameters
|
|
141
|
+
const parameters = allParams.map(param => ({
|
|
142
|
+
name: param.name,
|
|
143
|
+
in: param.in,
|
|
144
|
+
required: param.required || false,
|
|
145
|
+
description: param.description,
|
|
146
|
+
schema: isV3
|
|
147
|
+
? extractSchema(param.schema)
|
|
148
|
+
: extractSchemaV2(param),
|
|
149
|
+
}));
|
|
150
|
+
// Extract request body
|
|
151
|
+
let requestBody;
|
|
152
|
+
if (isV3) {
|
|
153
|
+
const v3Op = operation;
|
|
154
|
+
if (v3Op.requestBody && 'content' in v3Op.requestBody) {
|
|
155
|
+
const rb = v3Op.requestBody;
|
|
156
|
+
const contentType = Object.keys(rb.content)[0] || 'application/json';
|
|
157
|
+
const mediaType = rb.content[contentType];
|
|
158
|
+
requestBody = {
|
|
159
|
+
required: rb.required || false,
|
|
160
|
+
contentType,
|
|
161
|
+
schema: mediaType?.schema,
|
|
162
|
+
example: mediaType?.example || mediaType?.schema?.example,
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
167
|
+
const v2Op = operation;
|
|
168
|
+
const bodyParam = allParams.find(p => p.in === 'body');
|
|
169
|
+
if (bodyParam) {
|
|
170
|
+
requestBody = {
|
|
171
|
+
required: bodyParam.required || false,
|
|
172
|
+
contentType: 'application/json',
|
|
173
|
+
schema: bodyParam.schema,
|
|
174
|
+
example: bodyParam.schema?.example,
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
// Extract responses
|
|
179
|
+
const responses = [];
|
|
180
|
+
for (const [statusCode, response] of Object.entries(operation.responses || {})) {
|
|
181
|
+
if (!response || '$ref' in response)
|
|
182
|
+
continue;
|
|
183
|
+
const resp = response;
|
|
184
|
+
let example;
|
|
185
|
+
let schema;
|
|
186
|
+
if (isV3) {
|
|
187
|
+
const v3Resp = resp;
|
|
188
|
+
const content = v3Resp.content?.['application/json'];
|
|
189
|
+
schema = content?.schema;
|
|
190
|
+
example = content?.example || content?.schema?.example;
|
|
191
|
+
}
|
|
192
|
+
else {
|
|
193
|
+
const v2Resp = resp;
|
|
194
|
+
schema = v2Resp.schema;
|
|
195
|
+
example = v2Resp.schema?.example;
|
|
196
|
+
}
|
|
197
|
+
responses.push({
|
|
198
|
+
statusCode,
|
|
199
|
+
description: resp.description,
|
|
200
|
+
schema,
|
|
201
|
+
example,
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
// Generate operation ID if not present
|
|
205
|
+
const operationId = operation.operationId || `${method}_${path.replace(/[^a-zA-Z0-9]/g, '_')}`;
|
|
206
|
+
return {
|
|
207
|
+
operationId,
|
|
208
|
+
method,
|
|
209
|
+
path,
|
|
210
|
+
summary: operation.summary,
|
|
211
|
+
description: operation.description,
|
|
212
|
+
tags: operation.tags || [],
|
|
213
|
+
parameters,
|
|
214
|
+
requestBody,
|
|
215
|
+
responses,
|
|
216
|
+
security: operation.security,
|
|
217
|
+
deprecated: operation.deprecated,
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
function extractSchema(schema) {
|
|
221
|
+
if (!schema)
|
|
222
|
+
return undefined;
|
|
223
|
+
return {
|
|
224
|
+
type: schema.type || 'string',
|
|
225
|
+
format: schema.format,
|
|
226
|
+
default: schema.default,
|
|
227
|
+
example: schema.example,
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
function extractSchemaV2(param) {
|
|
231
|
+
if (!('type' in param))
|
|
232
|
+
return undefined;
|
|
233
|
+
const p = param;
|
|
234
|
+
return {
|
|
235
|
+
type: p.type || 'string',
|
|
236
|
+
format: p.format,
|
|
237
|
+
default: p.default,
|
|
238
|
+
example: undefined, // V2 doesn't have example on parameters
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
function extractSecurityScheme(scheme) {
|
|
242
|
+
return {
|
|
243
|
+
type: scheme.type,
|
|
244
|
+
name: 'name' in scheme ? scheme.name : undefined,
|
|
245
|
+
in: 'in' in scheme ? scheme.in : undefined,
|
|
246
|
+
scheme: 'scheme' in scheme ? scheme.scheme : undefined,
|
|
247
|
+
bearerFormat: 'bearerFormat' in scheme ? scheme.bearerFormat : undefined,
|
|
248
|
+
description: scheme.description,
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
function extractSecuritySchemeV2(scheme) {
|
|
252
|
+
return {
|
|
253
|
+
type: scheme.type === 'basic' ? 'http' : scheme.type,
|
|
254
|
+
name: 'name' in scheme ? scheme.name : undefined,
|
|
255
|
+
in: 'in' in scheme ? scheme.in : undefined,
|
|
256
|
+
scheme: scheme.type === 'basic' ? 'basic' : undefined,
|
|
257
|
+
description: scheme.description,
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* Generate test files from selected endpoints
|
|
262
|
+
*/
|
|
263
|
+
function generateTestFiles(spec, selectedEndpoints, options) {
|
|
264
|
+
const endpoints = spec.endpoints.filter(e => selectedEndpoints.includes(e.operationId));
|
|
265
|
+
if (endpoints.length === 0) {
|
|
266
|
+
return [];
|
|
267
|
+
}
|
|
268
|
+
switch (options.fileStrategy) {
|
|
269
|
+
case 'single':
|
|
270
|
+
return [generateSingleFile(spec, endpoints, options)];
|
|
271
|
+
case 'per-tag':
|
|
272
|
+
return generatePerTagFiles(spec, endpoints, options);
|
|
273
|
+
case 'per-path':
|
|
274
|
+
return generatePerPathFiles(spec, endpoints, options);
|
|
275
|
+
default:
|
|
276
|
+
return [generateSingleFile(spec, endpoints, options)];
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
function generateSingleFile(spec, endpoints, options) {
|
|
280
|
+
const variables = extractVariables(endpoints, options);
|
|
281
|
+
const tests = endpoints.map(endpoint => generateTestCase(endpoint, options));
|
|
282
|
+
const testFile = {
|
|
283
|
+
version: '1.0.0',
|
|
284
|
+
name: spec.info.title,
|
|
285
|
+
description: spec.info.description || `API tests generated from ${spec.info.title} v${spec.info.version}`,
|
|
286
|
+
variables,
|
|
287
|
+
tests,
|
|
288
|
+
};
|
|
289
|
+
const fileName = sanitizeFileName(spec.info.title) + '.testblocks.json';
|
|
290
|
+
return { fileName, testFile };
|
|
291
|
+
}
|
|
292
|
+
function generatePerTagFiles(spec, endpoints, options) {
|
|
293
|
+
// Group endpoints by tag
|
|
294
|
+
const byTag = new Map();
|
|
295
|
+
for (const endpoint of endpoints) {
|
|
296
|
+
const tag = endpoint.tags[0] || 'default';
|
|
297
|
+
if (!byTag.has(tag)) {
|
|
298
|
+
byTag.set(tag, []);
|
|
299
|
+
}
|
|
300
|
+
byTag.get(tag).push(endpoint);
|
|
301
|
+
}
|
|
302
|
+
const files = [];
|
|
303
|
+
for (const [tag, tagEndpoints] of byTag) {
|
|
304
|
+
const variables = extractVariables(tagEndpoints, options);
|
|
305
|
+
const tests = tagEndpoints.map(endpoint => generateTestCase(endpoint, options));
|
|
306
|
+
const tagInfo = spec.tags.find(t => t.name === tag);
|
|
307
|
+
const testFile = {
|
|
308
|
+
version: '1.0.0',
|
|
309
|
+
name: `${spec.info.title} - ${tag}`,
|
|
310
|
+
description: tagInfo?.description || `API tests for ${tag}`,
|
|
311
|
+
variables,
|
|
312
|
+
tests,
|
|
313
|
+
};
|
|
314
|
+
const fileName = sanitizeFileName(`${spec.info.title}-${tag}`) + '.testblocks.json';
|
|
315
|
+
files.push({ fileName, testFile });
|
|
316
|
+
}
|
|
317
|
+
return files;
|
|
318
|
+
}
|
|
319
|
+
function generatePerPathFiles(spec, endpoints, options) {
|
|
320
|
+
// Group endpoints by base path (first segment)
|
|
321
|
+
const byPath = new Map();
|
|
322
|
+
for (const endpoint of endpoints) {
|
|
323
|
+
const segments = endpoint.path.split('/').filter(Boolean);
|
|
324
|
+
const basePath = segments[0] || 'root';
|
|
325
|
+
if (!byPath.has(basePath)) {
|
|
326
|
+
byPath.set(basePath, []);
|
|
327
|
+
}
|
|
328
|
+
byPath.get(basePath).push(endpoint);
|
|
329
|
+
}
|
|
330
|
+
const files = [];
|
|
331
|
+
for (const [basePath, pathEndpoints] of byPath) {
|
|
332
|
+
const variables = extractVariables(pathEndpoints, options);
|
|
333
|
+
const tests = pathEndpoints.map(endpoint => generateTestCase(endpoint, options));
|
|
334
|
+
const testFile = {
|
|
335
|
+
version: '1.0.0',
|
|
336
|
+
name: `${spec.info.title} - /${basePath}`,
|
|
337
|
+
description: `API tests for /${basePath} endpoints`,
|
|
338
|
+
variables,
|
|
339
|
+
tests,
|
|
340
|
+
};
|
|
341
|
+
const fileName = sanitizeFileName(`${spec.info.title}-${basePath}`) + '.testblocks.json';
|
|
342
|
+
files.push({ fileName, testFile });
|
|
343
|
+
}
|
|
344
|
+
return files;
|
|
345
|
+
}
|
|
346
|
+
function extractVariables(endpoints, options) {
|
|
347
|
+
const variables = {
|
|
348
|
+
baseUrl: {
|
|
349
|
+
type: 'string',
|
|
350
|
+
default: options.baseUrl || '',
|
|
351
|
+
description: 'API base URL',
|
|
352
|
+
},
|
|
353
|
+
};
|
|
354
|
+
// Extract unique path parameters
|
|
355
|
+
const pathParams = new Set();
|
|
356
|
+
for (const endpoint of endpoints) {
|
|
357
|
+
for (const param of endpoint.parameters) {
|
|
358
|
+
if (param.in === 'path') {
|
|
359
|
+
pathParams.add(param.name);
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
for (const paramName of pathParams) {
|
|
364
|
+
const param = endpoints
|
|
365
|
+
.flatMap(e => e.parameters)
|
|
366
|
+
.find(p => p.name === paramName && p.in === 'path');
|
|
367
|
+
variables[paramName] = {
|
|
368
|
+
type: (param?.schema?.type || 'string'),
|
|
369
|
+
default: param?.schema?.example || param?.schema?.default || '',
|
|
370
|
+
description: param?.description || `Path parameter: ${paramName}`,
|
|
371
|
+
};
|
|
372
|
+
}
|
|
373
|
+
return variables;
|
|
374
|
+
}
|
|
375
|
+
function generateTestCase(endpoint, options) {
|
|
376
|
+
const steps = [];
|
|
377
|
+
// Generate API call step
|
|
378
|
+
const apiStep = generateApiCallStep(endpoint, options);
|
|
379
|
+
steps.push(apiStep);
|
|
380
|
+
// Generate assertion step if enabled
|
|
381
|
+
if (options.generateAssertions) {
|
|
382
|
+
const assertionStep = generateAssertionStep(endpoint);
|
|
383
|
+
if (assertionStep) {
|
|
384
|
+
steps.push(assertionStep);
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
return {
|
|
388
|
+
id: `test-${endpoint.operationId}-${Date.now()}`,
|
|
389
|
+
name: `${endpoint.method.toUpperCase()} ${endpoint.path}`,
|
|
390
|
+
description: endpoint.summary || endpoint.description,
|
|
391
|
+
tags: endpoint.tags,
|
|
392
|
+
steps,
|
|
393
|
+
};
|
|
394
|
+
}
|
|
395
|
+
function generateApiCallStep(endpoint, options) {
|
|
396
|
+
const blockType = `api_${endpoint.method}`;
|
|
397
|
+
// Convert path parameters from {param} to ${param}
|
|
398
|
+
const urlPath = endpoint.path.replace(/\{([^}]+)\}/g, '${$1}');
|
|
399
|
+
const url = `\${baseUrl}${urlPath}`;
|
|
400
|
+
const params = {
|
|
401
|
+
URL: url,
|
|
402
|
+
};
|
|
403
|
+
// Add request body for POST/PUT/PATCH
|
|
404
|
+
if (['post', 'put', 'patch'].includes(endpoint.method) && endpoint.requestBody) {
|
|
405
|
+
let body = '{}';
|
|
406
|
+
if (options.includeExamples && endpoint.requestBody.example) {
|
|
407
|
+
body = JSON.stringify(endpoint.requestBody.example, null, 2);
|
|
408
|
+
}
|
|
409
|
+
else if (endpoint.requestBody.schema) {
|
|
410
|
+
body = generateSchemaExample(endpoint.requestBody.schema);
|
|
411
|
+
}
|
|
412
|
+
params.BODY = body;
|
|
413
|
+
}
|
|
414
|
+
return {
|
|
415
|
+
id: `step-${endpoint.operationId}-call-${Date.now()}`,
|
|
416
|
+
type: blockType,
|
|
417
|
+
params,
|
|
418
|
+
};
|
|
419
|
+
}
|
|
420
|
+
function generateAssertionStep(endpoint) {
|
|
421
|
+
// Find the first 2xx response
|
|
422
|
+
const successResponse = endpoint.responses.find(r => r.statusCode.startsWith('2'));
|
|
423
|
+
if (!successResponse) {
|
|
424
|
+
return null;
|
|
425
|
+
}
|
|
426
|
+
const statusCode = parseInt(successResponse.statusCode, 10);
|
|
427
|
+
return {
|
|
428
|
+
id: `step-${endpoint.operationId}-assert-${Date.now()}`,
|
|
429
|
+
type: 'api_assert_status',
|
|
430
|
+
params: {
|
|
431
|
+
STATUS: isNaN(statusCode) ? 200 : statusCode,
|
|
432
|
+
},
|
|
433
|
+
};
|
|
434
|
+
}
|
|
435
|
+
function generateSchemaExample(schema) {
|
|
436
|
+
// Simple schema-to-example generation
|
|
437
|
+
const type = schema.type;
|
|
438
|
+
if (schema.example !== undefined) {
|
|
439
|
+
return JSON.stringify(schema.example, null, 2);
|
|
440
|
+
}
|
|
441
|
+
switch (type) {
|
|
442
|
+
case 'object': {
|
|
443
|
+
const properties = schema.properties;
|
|
444
|
+
if (!properties)
|
|
445
|
+
return '{}';
|
|
446
|
+
const obj = {};
|
|
447
|
+
for (const [key, prop] of Object.entries(properties)) {
|
|
448
|
+
obj[key] = getDefaultValueForType(prop.type, prop.example, prop.format);
|
|
449
|
+
}
|
|
450
|
+
return JSON.stringify(obj, null, 2);
|
|
451
|
+
}
|
|
452
|
+
case 'array': {
|
|
453
|
+
const items = schema.items;
|
|
454
|
+
if (!items)
|
|
455
|
+
return '[]';
|
|
456
|
+
const itemValue = getDefaultValueForType(items.type, items.example, items.format);
|
|
457
|
+
return JSON.stringify([itemValue], null, 2);
|
|
458
|
+
}
|
|
459
|
+
default:
|
|
460
|
+
return '{}';
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
function getDefaultValueForType(type, example, format) {
|
|
464
|
+
if (example !== undefined)
|
|
465
|
+
return example;
|
|
466
|
+
switch (type) {
|
|
467
|
+
case 'string':
|
|
468
|
+
if (format === 'email')
|
|
469
|
+
return 'user@example.com';
|
|
470
|
+
if (format === 'date')
|
|
471
|
+
return '2024-01-01';
|
|
472
|
+
if (format === 'date-time')
|
|
473
|
+
return '2024-01-01T00:00:00Z';
|
|
474
|
+
if (format === 'uuid')
|
|
475
|
+
return '00000000-0000-0000-0000-000000000000';
|
|
476
|
+
return 'string';
|
|
477
|
+
case 'integer':
|
|
478
|
+
case 'number':
|
|
479
|
+
return 0;
|
|
480
|
+
case 'boolean':
|
|
481
|
+
return true;
|
|
482
|
+
case 'array':
|
|
483
|
+
return [];
|
|
484
|
+
case 'object':
|
|
485
|
+
return {};
|
|
486
|
+
default:
|
|
487
|
+
return null;
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
function sanitizeFileName(name) {
|
|
491
|
+
return name
|
|
492
|
+
.toLowerCase()
|
|
493
|
+
.replace(/[^a-z0-9]+/g, '-')
|
|
494
|
+
.replace(/^-|-$/g, '');
|
|
495
|
+
}
|
|
@@ -140,6 +140,7 @@ async function startServer(options = {}) {
|
|
|
140
140
|
// Set directories
|
|
141
141
|
const pluginsDir = options.pluginsDir || path_1.default.join(workingDir, 'plugins');
|
|
142
142
|
const globalsDir = options.globalsDir || workingDir;
|
|
143
|
+
const projectDir = options.projectDir ? path_1.default.resolve(options.projectDir) : null;
|
|
143
144
|
(0, plugins_1.setPluginsDirectory)(pluginsDir);
|
|
144
145
|
(0, globals_1.setGlobalsDirectory)(globalsDir);
|
|
145
146
|
// Load plugins and globals
|
|
@@ -167,6 +168,166 @@ async function startServer(options = {}) {
|
|
|
167
168
|
app.get('/api/version', (_req, res) => {
|
|
168
169
|
res.json({ version: VERSION });
|
|
169
170
|
});
|
|
171
|
+
// Initial project directory (for auto-open)
|
|
172
|
+
app.get('/api/initial-project', (_req, res) => {
|
|
173
|
+
res.json({ projectDir });
|
|
174
|
+
});
|
|
175
|
+
// Server-side file system access (when projectDir is specified)
|
|
176
|
+
// List files in project directory
|
|
177
|
+
app.get('/api/project/files', async (_req, res) => {
|
|
178
|
+
if (!projectDir) {
|
|
179
|
+
return res.status(400).json({ error: 'No project directory configured' });
|
|
180
|
+
}
|
|
181
|
+
try {
|
|
182
|
+
const scanDir = async (dirPath, relativePath = '') => {
|
|
183
|
+
const entries = await fs_1.default.promises.readdir(dirPath, { withFileTypes: true });
|
|
184
|
+
const items = [];
|
|
185
|
+
for (const entry of entries) {
|
|
186
|
+
// Skip hidden files and common non-project directories
|
|
187
|
+
if (entry.name.startsWith('.') || entry.name === 'node_modules') {
|
|
188
|
+
continue;
|
|
189
|
+
}
|
|
190
|
+
const entryRelativePath = relativePath ? `${relativePath}/${entry.name}` : entry.name;
|
|
191
|
+
const fullPath = path_1.default.join(dirPath, entry.name);
|
|
192
|
+
if (entry.isDirectory()) {
|
|
193
|
+
const children = await scanDir(fullPath, entryRelativePath);
|
|
194
|
+
items.push({
|
|
195
|
+
name: entry.name,
|
|
196
|
+
path: entryRelativePath,
|
|
197
|
+
type: 'folder',
|
|
198
|
+
children,
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
else if (entry.name.endsWith('.testblocks.json') || entry.name === 'globals.json') {
|
|
202
|
+
items.push({
|
|
203
|
+
name: entry.name,
|
|
204
|
+
path: entryRelativePath,
|
|
205
|
+
type: 'file',
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
// Sort: folders first, then alphabetically
|
|
210
|
+
items.sort((a, b) => {
|
|
211
|
+
const aObj = a;
|
|
212
|
+
const bObj = b;
|
|
213
|
+
if (aObj.type !== bObj.type) {
|
|
214
|
+
return aObj.type === 'folder' ? -1 : 1;
|
|
215
|
+
}
|
|
216
|
+
return aObj.name.localeCompare(bObj.name);
|
|
217
|
+
});
|
|
218
|
+
return items;
|
|
219
|
+
};
|
|
220
|
+
const files = await scanDir(projectDir);
|
|
221
|
+
res.json({
|
|
222
|
+
projectDir,
|
|
223
|
+
name: path_1.default.basename(projectDir),
|
|
224
|
+
files,
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
catch (error) {
|
|
228
|
+
res.status(500).json({ error: error.message });
|
|
229
|
+
}
|
|
230
|
+
});
|
|
231
|
+
// Read a file from project directory
|
|
232
|
+
app.get('/api/project/read', async (req, res) => {
|
|
233
|
+
if (!projectDir) {
|
|
234
|
+
return res.status(400).json({ error: 'No project directory configured' });
|
|
235
|
+
}
|
|
236
|
+
const filePath = req.query.path;
|
|
237
|
+
if (!filePath) {
|
|
238
|
+
return res.status(400).json({ error: 'File path is required' });
|
|
239
|
+
}
|
|
240
|
+
// Security: ensure path doesn't escape project directory
|
|
241
|
+
const fullPath = path_1.default.resolve(projectDir, filePath);
|
|
242
|
+
if (!fullPath.startsWith(projectDir)) {
|
|
243
|
+
return res.status(403).json({ error: 'Access denied' });
|
|
244
|
+
}
|
|
245
|
+
try {
|
|
246
|
+
const content = await fs_1.default.promises.readFile(fullPath, 'utf-8');
|
|
247
|
+
res.json({ content: JSON.parse(content) });
|
|
248
|
+
}
|
|
249
|
+
catch (error) {
|
|
250
|
+
res.status(500).json({ error: error.message });
|
|
251
|
+
}
|
|
252
|
+
});
|
|
253
|
+
// Write a file to project directory
|
|
254
|
+
app.post('/api/project/write', async (req, res) => {
|
|
255
|
+
if (!projectDir) {
|
|
256
|
+
return res.status(400).json({ error: 'No project directory configured' });
|
|
257
|
+
}
|
|
258
|
+
const { path: filePath, content } = req.body;
|
|
259
|
+
if (!filePath) {
|
|
260
|
+
return res.status(400).json({ error: 'File path is required' });
|
|
261
|
+
}
|
|
262
|
+
// Security: ensure path doesn't escape project directory
|
|
263
|
+
const fullPath = path_1.default.resolve(projectDir, filePath);
|
|
264
|
+
if (!fullPath.startsWith(projectDir)) {
|
|
265
|
+
return res.status(403).json({ error: 'Access denied' });
|
|
266
|
+
}
|
|
267
|
+
try {
|
|
268
|
+
// Ensure parent directory exists
|
|
269
|
+
await fs_1.default.promises.mkdir(path_1.default.dirname(fullPath), { recursive: true });
|
|
270
|
+
await fs_1.default.promises.writeFile(fullPath, JSON.stringify(content, null, 2));
|
|
271
|
+
res.json({ success: true });
|
|
272
|
+
}
|
|
273
|
+
catch (error) {
|
|
274
|
+
res.status(500).json({ error: error.message });
|
|
275
|
+
}
|
|
276
|
+
});
|
|
277
|
+
// Create a new file in project directory
|
|
278
|
+
app.post('/api/project/create', async (req, res) => {
|
|
279
|
+
if (!projectDir) {
|
|
280
|
+
return res.status(400).json({ error: 'No project directory configured' });
|
|
281
|
+
}
|
|
282
|
+
const { path: filePath, content } = req.body;
|
|
283
|
+
if (!filePath) {
|
|
284
|
+
return res.status(400).json({ error: 'File path is required' });
|
|
285
|
+
}
|
|
286
|
+
// Security: ensure path doesn't escape project directory
|
|
287
|
+
const fullPath = path_1.default.resolve(projectDir, filePath);
|
|
288
|
+
if (!fullPath.startsWith(projectDir)) {
|
|
289
|
+
return res.status(403).json({ error: 'Access denied' });
|
|
290
|
+
}
|
|
291
|
+
try {
|
|
292
|
+
// Check if file already exists
|
|
293
|
+
try {
|
|
294
|
+
await fs_1.default.promises.access(fullPath);
|
|
295
|
+
return res.status(409).json({ error: 'File already exists' });
|
|
296
|
+
}
|
|
297
|
+
catch {
|
|
298
|
+
// File doesn't exist, good
|
|
299
|
+
}
|
|
300
|
+
// Ensure parent directory exists
|
|
301
|
+
await fs_1.default.promises.mkdir(path_1.default.dirname(fullPath), { recursive: true });
|
|
302
|
+
await fs_1.default.promises.writeFile(fullPath, JSON.stringify(content, null, 2));
|
|
303
|
+
res.json({ success: true });
|
|
304
|
+
}
|
|
305
|
+
catch (error) {
|
|
306
|
+
res.status(500).json({ error: error.message });
|
|
307
|
+
}
|
|
308
|
+
});
|
|
309
|
+
// Delete a file from project directory
|
|
310
|
+
app.delete('/api/project/delete', async (req, res) => {
|
|
311
|
+
if (!projectDir) {
|
|
312
|
+
return res.status(400).json({ error: 'No project directory configured' });
|
|
313
|
+
}
|
|
314
|
+
const filePath = req.query.path;
|
|
315
|
+
if (!filePath) {
|
|
316
|
+
return res.status(400).json({ error: 'File path is required' });
|
|
317
|
+
}
|
|
318
|
+
// Security: ensure path doesn't escape project directory
|
|
319
|
+
const fullPath = path_1.default.resolve(projectDir, filePath);
|
|
320
|
+
if (!fullPath.startsWith(projectDir)) {
|
|
321
|
+
return res.status(403).json({ error: 'Access denied' });
|
|
322
|
+
}
|
|
323
|
+
try {
|
|
324
|
+
await fs_1.default.promises.unlink(fullPath);
|
|
325
|
+
res.json({ success: true });
|
|
326
|
+
}
|
|
327
|
+
catch (error) {
|
|
328
|
+
res.status(500).json({ error: error.message });
|
|
329
|
+
}
|
|
330
|
+
});
|
|
170
331
|
// List available plugins (with full block definitions for client registration)
|
|
171
332
|
app.get('/api/plugins', (_req, res) => {
|
|
172
333
|
const available = (0, plugins_1.discoverPlugins)();
|
|
@@ -517,6 +678,9 @@ async function startServer(options = {}) {
|
|
|
517
678
|
console.log(` Working directory: ${workingDir}`);
|
|
518
679
|
console.log(` Plugins: ${pluginsDir}`);
|
|
519
680
|
console.log(` Globals: ${globalsDir}`);
|
|
681
|
+
if (projectDir) {
|
|
682
|
+
console.log(` Project (auto-open): ${projectDir}`);
|
|
683
|
+
}
|
|
520
684
|
console.log('\nPress Ctrl+C to stop\n');
|
|
521
685
|
// Open browser if requested
|
|
522
686
|
if (options.open) {
|